From 5da0b7bf83fb86b209b7c831faa2c8625025ad43 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 23 May 2013 12:02:58 +0200 Subject: [PATCH] SONAR-4330 Create the metrics "False-Positive", "Open status", "Reopened status" and "Confirmed status" issues --- .../core/issue/CountOpenIssuesDecorator.java | 20 ++++++++- .../resources/org/sonar/l10n/core.properties | 14 +++++-- .../issue/CountOpenIssuesDecoratorTest.java | 42 ++++++++++++++++++- .../org/sonar/api/measures/CoreMetrics.java | 30 ++++++++++--- 4 files changed, 94 insertions(+), 12 deletions(-) diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountOpenIssuesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountOpenIssuesDecorator.java index 4a4a51fa766..caa11749904 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountOpenIssuesDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountOpenIssuesDecorator.java @@ -79,7 +79,10 @@ public class CountOpenIssuesDecorator implements Decorator { CoreMetrics.NEW_MAJOR_ISSUES, CoreMetrics.NEW_MINOR_ISSUES, CoreMetrics.NEW_INFO_ISSUES, - CoreMetrics.UNASSIGNED_ISSUES + CoreMetrics.UNASSIGNED_ISSUES, + CoreMetrics.OPEN_ISSUES, + CoreMetrics.REOPENED_ISSUES, + CoreMetrics.CONFIRMED_ISSUES ); } @@ -93,6 +96,9 @@ public class CountOpenIssuesDecorator implements Decorator { Map> rulesPerSeverity = Maps.newHashMap(); ListMultimap issuesPerSeverity = ArrayListMultimap.create(); int countUnassigned = 0; + int countOpen = 0; + int countReopened = 0; + int countConfirmed = 0; for (Issue issue : issues) { severityBag.add(RulePriority.valueOf(issue.severity())); @@ -103,6 +109,15 @@ public class CountOpenIssuesDecorator implements Decorator { if (issue.assignee() == null) { countUnassigned++; } + if (Issue.STATUS_OPEN.equals(issue.status())){ + countOpen++; + } + if (Issue.STATUS_REOPENED.equals(issue.status())){ + countReopened++; + } + if (Issue.STATUS_CONFIRMED.equals(issue.status())){ + countConfirmed++; + } } for (RulePriority ruleSeverity : RulePriority.values()) { @@ -116,6 +131,9 @@ public class CountOpenIssuesDecorator implements Decorator { saveNewIssues(context, issues, shouldSaveNewMetrics); saveMeasure(context, CoreMetrics.UNASSIGNED_ISSUES, countUnassigned); + saveMeasure(context, CoreMetrics.OPEN_ISSUES, countOpen); + saveMeasure(context, CoreMetrics.REOPENED_ISSUES, countReopened); + saveMeasure(context, CoreMetrics.CONFIRMED_ISSUES, countConfirmed); } } diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties index bf69c17b99b..5cf4f639a85 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -2303,7 +2303,6 @@ metric.issues_density.abbreviation=RCI metric.issues.name=Active issues metric.issues.description=Active open and reopened issues -metric.issues.abbreviation=Active issues metric.blocker_issues.name=Blocker issues metric.blocker_issues.description=Blocker issues @@ -2336,15 +2335,22 @@ metric.new_minor_issues.name=New Minor issues metric.new_minor_issues.description=New Minor issues metric.new_info_issues.name=New Info issues -metric.new_info_issues.description=New Info violations +metric.new_info_issues.description=New Info issues metric.false_positive_issues.name=False-positive issues metric.false_positive_issues.description=Active false-positive issues -metric.false_positive_issues.abbreviation=False-positive issues metric.unassigned_issues.name=Unassigned issues metric.unassigned_issues.description=Active unassigned issues -metric.unassigned_issues.abbreviation=Unassigned issues + +metric.open_issues.name=Open issues +metric.open_issues.description=Open issues + +metric.reopened_issues.name=Reopened issues +metric.reopened_issues.description=Reopened issues + +metric.confirmed_issues.name=Confirmed issues +metric.confirmed_issues.description=Confirmed issues #------------------------------------------------------------------------------ # diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/CountOpenIssuesDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/CountOpenIssuesDecoratorTest.java index 109aa467203..186d71d7432 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/CountOpenIssuesDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/CountOpenIssuesDecoratorTest.java @@ -111,7 +111,7 @@ public class CountOpenIssuesDecoratorTest { @Test public void should_be_depended_upon_metric() { - assertThat(decorator.generatesIssuesMetrics()).hasSize(13); + assertThat(decorator.generatesIssuesMetrics()).hasSize(16); } @Test @@ -219,6 +219,46 @@ public class CountOpenIssuesDecoratorTest { verify(context).saveMeasure(CoreMetrics.UNASSIGNED_ISSUES, 2.0); } + @Test + public void should_save_open_issues() { + List issues = newArrayList(); + issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setStatus(Issue.STATUS_OPEN).setSeverity(RulePriority.CRITICAL.name())); + issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setStatus(Issue.STATUS_REOPENED).setSeverity(RulePriority.CRITICAL.name())); + issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setStatus(Issue.STATUS_OPEN).setSeverity(RulePriority.CRITICAL.name())); + when(issuable.issues()).thenReturn(issues); + + decorator.decorate(resource, context); + + verify(context).saveMeasure(CoreMetrics.OPEN_ISSUES, 2.0); + } + + @Test + public void should_save_reopened_issues() { + List issues = newArrayList(); + issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setStatus(Issue.STATUS_OPEN).setSeverity(RulePriority.CRITICAL.name())); + issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setStatus(Issue.STATUS_REOPENED).setSeverity(RulePriority.CRITICAL.name())); + issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setStatus(Issue.STATUS_OPEN).setSeverity(RulePriority.CRITICAL.name())); + when(issuable.issues()).thenReturn(issues); + + decorator.decorate(resource, context); + + verify(context).saveMeasure(CoreMetrics.REOPENED_ISSUES, 1.0); + } + + + @Test + public void should_save_confirmed_issues() { + List issues = newArrayList(); + issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setStatus(Issue.STATUS_CONFIRMED).setSeverity(RulePriority.CRITICAL.name())); + issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setStatus(Issue.STATUS_REOPENED).setSeverity(RulePriority.CRITICAL.name())); + issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setStatus(Issue.STATUS_CONFIRMED).setSeverity(RulePriority.CRITICAL.name())); + when(issuable.issues()).thenReturn(issues); + + decorator.decorate(resource, context); + + verify(context).saveMeasure(CoreMetrics.CONFIRMED_ISSUES, 2.0); + } + @Test public void same_rule_should_have_different_severities() { List issues = newArrayList(); 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 89d7704c19d..17fc013a30e 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 @@ -1820,13 +1820,13 @@ public final class CoreMetrics { /** * @since 3.6 */ - public static final String UNPLANNED_ISSUES_KEY = "unplanned_issues"; + public static final String OPEN_ISSUES_KEY = "open_issues"; /** * @since 3.6 */ - public static final Metric UNPLANNED_ISSUES = new Metric.Builder(UNPLANNED_ISSUES_KEY, "Unplanned issues", Metric.ValueType.INT) - .setDescription("Active unplanned issues") + public static final Metric OPEN_ISSUES = new Metric.Builder(OPEN_ISSUES_KEY, "Open issues", Metric.ValueType.INT) + .setDescription("Open issues") .setDirection(Metric.DIRECTION_WORST) .setDomain(DOMAIN_ISSUES) .setBestValue(0.0) @@ -1836,13 +1836,31 @@ public final class CoreMetrics { /** * @since 3.6 */ - public static final String NEW_UNPLANNED_ISSUES_KEY = "new_unplanned_issues"; + public static final String REOPENED_ISSUES_KEY = "reopened_issues"; /** * @since 3.6 */ - public static final Metric NEW_UNPLANNED_ISSUES = new Metric.Builder(NEW_UNPLANNED_ISSUES_KEY, "New unplanned issues", Metric.ValueType.INT) - .setDescription("New issues that have not been planned yet") + public static final Metric REOPENED_ISSUES = new Metric.Builder(REOPENED_ISSUES_KEY, "Reopened issues", Metric.ValueType.INT) + .setDescription("Reopened issues") + .setDirection(Metric.DIRECTION_WORST) + .setQualitative(true) + .setDomain(DOMAIN_ISSUES) + .setBestValue(0.0) + .setOptimizedBestValue(true) + .setDeleteHistoricalData(true) + .create(); + + /** + * @since 3.6 + */ + public static final String CONFIRMED_ISSUES_KEY = "confirmed_issues"; + + /** + * @since 3.6 + */ + public static final Metric CONFIRMED_ISSUES = new Metric.Builder(CONFIRMED_ISSUES_KEY, "Confirmed issues", Metric.ValueType.INT) + .setDescription("Confirmed issues") .setDirection(Metric.DIRECTION_WORST) .setQualitative(true) .setDomain(DOMAIN_ISSUES) -- 2.39.5