import org.sonar.ce.task.projectanalysis.metric.Metric;
import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
import org.sonar.core.issue.DefaultIssue;
+import org.sonar.server.metric.SoftwareQualitiesMetrics;
import static org.sonar.api.measures.CoreMetrics.RELIABILITY_REMEDIATION_EFFORT_KEY;
import static org.sonar.api.measures.CoreMetrics.SECURITY_REMEDIATION_EFFORT_KEY;
import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY;
/**
* Compute effort related measures :
* {@link CoreMetrics#TECHNICAL_DEBT_KEY}
* {@link CoreMetrics#RELIABILITY_REMEDIATION_EFFORT_KEY}
* {@link CoreMetrics#SECURITY_REMEDIATION_EFFORT_KEY}
+ * {@link SoftwareQualitiesMetrics#SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY}
+ * {@link SoftwareQualitiesMetrics#SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY}
+ * {@link SoftwareQualitiesMetrics#SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY}
*/
public class EffortAggregator extends IssueVisitor {
private final Metric reliabilityEffortMetric;
private final Metric securityEffortMetric;
+ private final Metric softwareQualityMaintainabilityEffortMetric;
+ private final Metric softwareQualityReliabilityEffortMetric;
+ private final Metric softwareQualitySecurityEffortMetric;
+
private EffortCounter effortCounter;
public EffortAggregator(MetricRepository metricRepository, MeasureRepository measureRepository) {
this.measureRepository = measureRepository;
+
+ // Based on issue Type and Severity
this.maintainabilityEffortMetric = metricRepository.getByKey(TECHNICAL_DEBT_KEY);
this.reliabilityEffortMetric = metricRepository.getByKey(RELIABILITY_REMEDIATION_EFFORT_KEY);
this.securityEffortMetric = metricRepository.getByKey(SECURITY_REMEDIATION_EFFORT_KEY);
+
+ // Based on software qualities
+ this.softwareQualityMaintainabilityEffortMetric = metricRepository.getByKey(SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY);
+ this.softwareQualityReliabilityEffortMetric = metricRepository.getByKey(SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY);
+ this.softwareQualitySecurityEffortMetric = metricRepository.getByKey(SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY);
}
@Override
private void computeMaintainabilityEffortMeasure(Component component) {
measureRepository.add(component, maintainabilityEffortMetric, Measure.newMeasureBuilder().create(effortCounter.maintainabilityEffort));
+ measureRepository.add(component, softwareQualityMaintainabilityEffortMetric, Measure.newMeasureBuilder().create(effortCounter.softwareQualityMaintainabilityEffort));
}
private void computeReliabilityEffortMeasure(Component component) {
measureRepository.add(component, reliabilityEffortMetric, Measure.newMeasureBuilder().create(effortCounter.reliabilityEffort));
+ measureRepository.add(component, softwareQualityReliabilityEffortMetric, Measure.newMeasureBuilder().create(effortCounter.softwareQualityReliabilityEffort));
}
private void computeSecurityEffortMeasure(Component component) {
measureRepository.add(component, securityEffortMetric, Measure.newMeasureBuilder().create(effortCounter.securityEffort));
+ measureRepository.add(component, softwareQualitySecurityEffortMetric, Measure.newMeasureBuilder().create(effortCounter.softwareQualitySecurityEffort));
}
private static class EffortCounter {
private long reliabilityEffort = 0L;
private long securityEffort = 0L;
+ private long softwareQualityMaintainabilityEffort = 0L;
+ private long softwareQualityReliabilityEffort = 0L;
+ private long softwareQualitySecurityEffort = 0L;
+
void add(DefaultIssue issue) {
Long issueEffort = issue.effortInMinutes();
if (issueEffort != null && issueEffort != 0L) {
- switch (issue.type()) {
- case CODE_SMELL:
- maintainabilityEffort += issueEffort;
- break;
- case BUG:
- reliabilityEffort += issueEffort;
+ computeTypeEffort(issue, issueEffort);
+ computeSoftwareQualityEffort(issue, issueEffort);
+ }
+ }
+
+ private void computeSoftwareQualityEffort(DefaultIssue issue, Long issueEffort) {
+ issue.impacts().forEach((sq, severity) -> {
+ switch (sq) {
+ case MAINTAINABILITY:
+ softwareQualityMaintainabilityEffort += issueEffort;
break;
- case VULNERABILITY:
- securityEffort += issueEffort;
+ case RELIABILITY:
+ softwareQualityReliabilityEffort += issueEffort;
break;
- case SECURITY_HOTSPOT:
- // Not counted
+ case SECURITY:
+ softwareQualitySecurityEffort += issueEffort;
break;
default:
- throw new IllegalStateException(String.format("Unknown type '%s'", issue.type()));
+ throw new IllegalStateException(String.format("Unknown software quality '%s'", sq));
}
+ });
+ }
+
+ private void computeTypeEffort(DefaultIssue issue, Long issueEffort) {
+ switch (issue.type()) {
+ case CODE_SMELL:
+ maintainabilityEffort += issueEffort;
+ break;
+ case BUG:
+ reliabilityEffort += issueEffort;
+ break;
+ case VULNERABILITY:
+ securityEffort += issueEffort;
+ break;
+ case SECURITY_HOTSPOT:
+ // Not counted
+ break;
+ default:
+ throw new IllegalStateException(String.format("Unknown type '%s'", issue.type()));
}
}
maintainabilityEffort += effortCounter.maintainabilityEffort;
reliabilityEffort += effortCounter.reliabilityEffort;
securityEffort += effortCounter.securityEffort;
+
+ softwareQualityMaintainabilityEffort += effortCounter.softwareQualityMaintainabilityEffort;
+ softwareQualityReliabilityEffort += effortCounter.softwareQualityReliabilityEffort;
+ softwareQualitySecurityEffort += effortCounter.softwareQualitySecurityEffort;
}
}
}
import org.sonar.ce.task.projectanalysis.metric.Metric;
import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
import org.sonar.core.issue.DefaultIssue;
+import org.sonar.server.metric.SoftwareQualitiesMetrics;
import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_REMEDIATION_EFFORT_KEY;
import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT_KEY;
import static org.sonar.api.measures.CoreMetrics.NEW_TECHNICAL_DEBT_KEY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY;
/**
* Compute new effort related measures :
* {@link CoreMetrics#NEW_TECHNICAL_DEBT_KEY}
* {@link CoreMetrics#NEW_RELIABILITY_REMEDIATION_EFFORT_KEY}
* {@link CoreMetrics#NEW_SECURITY_REMEDIATION_EFFORT_KEY}
+ * {@link SoftwareQualitiesMetrics#NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY}
+ * {@link SoftwareQualitiesMetrics#NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY}
+ * {@link SoftwareQualitiesMetrics#NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY}
*/
public class NewEffortAggregator extends IssueVisitor {
private final Map<String, NewEffortCounter> counterByComponentUuid = new HashMap<>();
private final Metric newReliabilityEffortMetric;
private final Metric newSecurityEffortMetric;
private final NewIssueClassifier newIssueClassifier;
+ private final Metric newSoftwareQualityMaintainabilityEffortMetric;
+ private final Metric newSoftwareQualityReliabilityEffortMetric;
+ private final Metric newSoftwareQualitySecurityEffortMetric;
private NewEffortCounter counter = null;
public NewEffortAggregator(MetricRepository metricRepository, MeasureRepository measureRepository, NewIssueClassifier newIssueClassifier) {
this.measureRepository = measureRepository;
+ // Based on issue Type and Severity
this.newMaintainabilityEffortMetric = metricRepository.getByKey(NEW_TECHNICAL_DEBT_KEY);
this.newReliabilityEffortMetric = metricRepository.getByKey(NEW_RELIABILITY_REMEDIATION_EFFORT_KEY);
this.newSecurityEffortMetric = metricRepository.getByKey(NEW_SECURITY_REMEDIATION_EFFORT_KEY);
+
+ // Based on software qualities
+ this.newSoftwareQualityMaintainabilityEffortMetric = metricRepository.getByKey(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY);
+ this.newSoftwareQualityReliabilityEffortMetric = metricRepository.getByKey(NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY);
+ this.newSoftwareQualitySecurityEffortMetric = metricRepository.getByKey(NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY);
+
this.newIssueClassifier = newIssueClassifier;
}
computeMeasure(component, newMaintainabilityEffortMetric, counter.maintainabilitySum);
computeMeasure(component, newReliabilityEffortMetric, counter.reliabilitySum);
computeMeasure(component, newSecurityEffortMetric, counter.securitySum);
+
+ computeMeasure(component, newSoftwareQualityMaintainabilityEffortMetric, counter.softwareQualityMaintainabilitySum);
+ computeMeasure(component, newSoftwareQualityReliabilityEffortMetric, counter.softwareQualityReliabilitySum);
+ computeMeasure(component, newSoftwareQualitySecurityEffortMetric, counter.softwareQualitySecuritySum);
}
counter = null;
}
private final EffortSum reliabilitySum = new EffortSum();
private final EffortSum securitySum = new EffortSum();
+ private final EffortSum softwareQualityMaintainabilitySum = new EffortSum();
+ private final EffortSum softwareQualityReliabilitySum = new EffortSum();
+ private final EffortSum softwareQualitySecuritySum = new EffortSum();
+
void add(NewEffortCounter otherCounter) {
maintainabilitySum.add(otherCounter.maintainabilitySum);
reliabilitySum.add(otherCounter.reliabilitySum);
securitySum.add(otherCounter.securitySum);
+
+ softwareQualityMaintainabilitySum.add(otherCounter.softwareQualityMaintainabilitySum);
+ softwareQualityReliabilitySum.add(otherCounter.softwareQualityReliabilitySum);
+ softwareQualitySecuritySum.add(otherCounter.softwareQualitySecuritySum);
}
void add(Component component, DefaultIssue issue) {
long newEffort = calculate(component, issue);
+ computeTypeEffort(issue, newEffort);
+ computeSoftwareQualityEffort(issue, newEffort);
+ }
+
+ private void computeSoftwareQualityEffort(DefaultIssue issue, long newEffort) {
+ issue.impacts().forEach((sq, severity) -> {
+ switch (sq) {
+ case MAINTAINABILITY:
+ softwareQualityMaintainabilitySum.add(newEffort);
+ break;
+ case RELIABILITY:
+ softwareQualityReliabilitySum.add(newEffort);
+ break;
+ case SECURITY:
+ softwareQualitySecuritySum.add(newEffort);
+ break;
+ default:
+ throw new IllegalStateException(String.format("Unknown software quality '%s'", sq));
+ }
+ });
+ }
+
+ private void computeTypeEffort(DefaultIssue issue, long newEffort) {
switch (issue.type()) {
case CODE_SMELL:
maintainabilitySum.add(newEffort);
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit;
import org.sonar.ce.task.projectanalysis.component.PathAwareVisitorAdapter;
-import org.sonar.ce.task.projectanalysis.formula.counter.RatingValue;
import org.sonar.ce.task.projectanalysis.measure.Measure;
import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
import org.sonar.ce.task.projectanalysis.measure.RatingMeasures;
public static final class Counter {
private long devCosts = 0;
- private RatingValue reliabilityRating = new RatingValue();
- private RatingValue securityRating = new RatingValue();
private Counter() {
// prevents instantiation
void add(Counter otherCounter) {
addDevCosts(otherCounter.devCosts);
- reliabilityRating.increment(otherCounter.reliabilityRating);
- securityRating.increment(otherCounter.securityRating);
}
void addDevCosts(long developmentCosts) {
*/
package org.sonar.ce.task.projectanalysis.issue;
-import org.junit.Test;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.sonar.api.issue.impact.Severity;
+import org.sonar.api.issue.impact.SoftwareQuality;
import org.sonar.api.utils.Duration;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.ReportComponent;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
+import static org.sonar.api.issue.impact.Severity.HIGH;
+import static org.sonar.api.issue.impact.SoftwareQuality.MAINTAINABILITY;
+import static org.sonar.api.issue.impact.SoftwareQuality.RELIABILITY;
+import static org.sonar.api.issue.impact.SoftwareQuality.SECURITY;
import static org.sonar.api.measures.CoreMetrics.RELIABILITY_REMEDIATION_EFFORT;
import static org.sonar.api.measures.CoreMetrics.RELIABILITY_REMEDIATION_EFFORT_KEY;
import static org.sonar.api.measures.CoreMetrics.SECURITY_REMEDIATION_EFFORT;
import static org.sonar.api.rules.RuleType.BUG;
import static org.sonar.api.rules.RuleType.CODE_SMELL;
import static org.sonar.api.rules.RuleType.VULNERABILITY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY;
-public class EffortAggregatorTest {
+class EffortAggregatorTest {
static final Component FILE = ReportComponent.builder(Component.Type.FILE, 1).build();
static final Component PROJECT = ReportComponent.builder(Component.Type.PROJECT, 2).addChildren(FILE).build();
- @org.junit.Rule
+ @RegisterExtension
public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
.add(TECHNICAL_DEBT)
.add(RELIABILITY_REMEDIATION_EFFORT)
- .add(SECURITY_REMEDIATION_EFFORT);
+ .add(SECURITY_REMEDIATION_EFFORT)
+ .add(SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT)
+ .add(SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT)
+ .add(SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT);
- @org.junit.Rule
+ @RegisterExtension
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(PROJECT, metricRepository);
EffortAggregator underTest = new EffortAggregator(metricRepository, measureRepository);
@Test
- public void sum_maintainability_effort_of_unresolved_issues() {
- DefaultIssue unresolved1 = newCodeSmellIssue(10);
- DefaultIssue unresolved2 = newCodeSmellIssue(30);
- DefaultIssue unresolvedWithoutEffort = newCodeSmellIssueWithoutEffort();
- DefaultIssue resolved = newCodeSmellIssue(50).setResolution(RESOLUTION_FIXED);
+ void sum_maintainability_effort_of_unresolved_issues() {
+ DefaultIssue unresolved1 = newMaintainabilityIssue(10);
+ DefaultIssue unresolved2 = newMaintainabilityIssue(30);
+ DefaultIssue unresolvedWithoutEffort = newMaintainabilityIssueWithoutEffort();
+ DefaultIssue resolved = newMaintainabilityIssue(50).setResolution(RESOLUTION_FIXED);
underTest.beforeComponent(FILE);
underTest.onIssue(FILE, unresolved1);
// total maintainability effort
assertMeasure(FILE, TECHNICAL_DEBT_KEY, 10L + 30L);
+ assertMeasure(FILE, SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, 10L + 30L);
}
@Test
- public void maintainability_effort_is_only_computed_using_code_smell_issues() {
- DefaultIssue codeSmellIssue = newCodeSmellIssue(10);
+ void sum_effort_when_multiple_impacts() {
+ DefaultIssue unresolved1 = newIssue(10, Map.of(MAINTAINABILITY, HIGH, SECURITY, HIGH, RELIABILITY, HIGH));
+ DefaultIssue unresolved2 = newIssue(30, Map.of(MAINTAINABILITY, HIGH, SECURITY, HIGH, RELIABILITY, HIGH));
+
+ underTest.beforeComponent(FILE);
+ underTest.onIssue(FILE, unresolved1);
+ underTest.onIssue(FILE, unresolved2);
+ underTest.afterComponent(FILE);
+
+ // total maintainability effort
+ assertMeasure(FILE, SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, 10L + 30L);
+ assertMeasure(FILE, SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, 10L + 30L);
+ assertMeasure(FILE, SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, 10L + 30L);
+ }
+
+ @Test
+ void maintainability_effort_is_only_computed_using_maintainability_issues() {
+ DefaultIssue codeSmellIssue = newMaintainabilityIssue(10);
// Issues of type BUG and VULNERABILITY should be ignored
- DefaultIssue bugIssue = newBugIssue(15);
- DefaultIssue vulnerabilityIssue = newVulnerabilityIssue(12);
+ DefaultIssue bugIssue = newReliabilityIssue(15);
+ DefaultIssue vulnerabilityIssue = newSecurityIssue(12);
underTest.beforeComponent(FILE);
underTest.onIssue(FILE, codeSmellIssue);
// Only effort of CODE SMELL issue is used
assertMeasure(FILE, TECHNICAL_DEBT_KEY, 10L);
+ assertMeasure(FILE, SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, 10L);
+
}
@Test
- public void sum_reliability_effort_of_unresolved_issues() {
- DefaultIssue unresolved1 = newBugIssue(10);
- DefaultIssue unresolved2 = newBugIssue(30);
- DefaultIssue unresolvedWithoutEffort = newBugIssueWithoutEffort();
- DefaultIssue resolved = newBugIssue(50).setResolution(RESOLUTION_FIXED);
+ void sum_reliability_effort_of_unresolved_issues() {
+ DefaultIssue unresolved1 = newReliabilityIssue(10);
+ DefaultIssue unresolved2 = newReliabilityIssue(30);
+ DefaultIssue unresolvedWithoutEffort = newReliabilityIssueWithoutEffort();
+ DefaultIssue resolved = newReliabilityIssue(50).setResolution(RESOLUTION_FIXED);
underTest.beforeComponent(FILE);
underTest.onIssue(FILE, unresolved1);
underTest.afterComponent(FILE);
assertMeasure(FILE, RELIABILITY_REMEDIATION_EFFORT_KEY, 10L + 30L);
+ assertMeasure(FILE, SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, 10L + 30L);
}
@Test
- public void reliability_effort_is_only_computed_using_bug_issues() {
- DefaultIssue bugIssue = newBugIssue(10);
+ void reliability_effort_is_only_computed_using_reliability_issues() {
+ DefaultIssue bugIssue = newReliabilityIssue(10);
// Issues of type CODE SMELL and VULNERABILITY should be ignored
- DefaultIssue codeSmellIssue = newCodeSmellIssue(15);
- DefaultIssue vulnerabilityIssue = newVulnerabilityIssue(12);
+ DefaultIssue codeSmellIssue = newMaintainabilityIssue(15);
+ DefaultIssue vulnerabilityIssue = newSecurityIssue(12);
underTest.beforeComponent(FILE);
underTest.onIssue(FILE, bugIssue);
// Only effort of BUG issue is used
assertMeasure(FILE, RELIABILITY_REMEDIATION_EFFORT_KEY, 10L);
+ assertMeasure(FILE, SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, 10L);
}
@Test
- public void sum_security_effort_of_unresolved_issues() {
- DefaultIssue unresolved1 = newVulnerabilityIssue(10);
- DefaultIssue unresolved2 = newVulnerabilityIssue(30);
- DefaultIssue unresolvedWithoutEffort = newVulnerabilityIssueWithoutEffort();
- DefaultIssue resolved = newVulnerabilityIssue(50).setResolution(RESOLUTION_FIXED);
+ void sum_security_effort_of_unresolved_issues() {
+ DefaultIssue unresolved1 = newSecurityIssue(10);
+ DefaultIssue unresolved2 = newSecurityIssue(30);
+ DefaultIssue unresolvedWithoutEffort = newSecurityIssueWithoutEffort();
+ DefaultIssue resolved = newSecurityIssue(50).setResolution(RESOLUTION_FIXED);
underTest.beforeComponent(FILE);
underTest.onIssue(FILE, unresolved1);
underTest.afterComponent(FILE);
assertMeasure(FILE, SECURITY_REMEDIATION_EFFORT_KEY, 10L + 30L);
+ assertMeasure(FILE, SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, 10L + 30L);
}
@Test
- public void security_effort_is_only_computed_using_code_smell_issues() {
- DefaultIssue vulnerabilityIssue = newVulnerabilityIssue(10);
+ void security_effort_is_only_computed_using_maintainability_issues() {
+ DefaultIssue vulnerabilityIssue = newSecurityIssue(10);
// Issues of type BUG and CODE SMELL should be ignored
- DefaultIssue bugIssue = newBugIssue(15);
- DefaultIssue codeSmellIssue = newCodeSmellIssue(12);
+ DefaultIssue bugIssue = newReliabilityIssue(15);
+ DefaultIssue codeSmellIssue = newMaintainabilityIssue(12);
underTest.beforeComponent(FILE);
underTest.onIssue(FILE, vulnerabilityIssue);
// Only effort of VULNERABILITY issue is used
assertMeasure(FILE, SECURITY_REMEDIATION_EFFORT_KEY, 10L);
+ assertMeasure(FILE, SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, 10L);
}
@Test
- public void aggregate_maintainability_measures_of_children() {
+ void aggregate_maintainability_measures_of_children() {
underTest.beforeComponent(FILE);
- underTest.onIssue(FILE, newCodeSmellIssue(10));
- underTest.onIssue(FILE, newBugIssue(8));
- underTest.onIssue(FILE, newVulnerabilityIssue(12));
+ underTest.onIssue(FILE, newMaintainabilityIssue(10));
+ underTest.onIssue(FILE, newReliabilityIssue(8));
+ underTest.onIssue(FILE, newSecurityIssue(12));
underTest.afterComponent(FILE);
underTest.beforeComponent(PROJECT);
- underTest.onIssue(PROJECT, newCodeSmellIssue(30));
- underTest.onIssue(PROJECT, newBugIssue(38));
- underTest.onIssue(PROJECT, newVulnerabilityIssue(42));
+ underTest.onIssue(PROJECT, newMaintainabilityIssue(30));
+ underTest.onIssue(PROJECT, newReliabilityIssue(38));
+ underTest.onIssue(PROJECT, newSecurityIssue(42));
underTest.afterComponent(PROJECT);
assertMeasure(PROJECT, TECHNICAL_DEBT_KEY, 10L + 30L);
assertMeasure(PROJECT, RELIABILITY_REMEDIATION_EFFORT_KEY, 8L + 38L);
assertMeasure(PROJECT, SECURITY_REMEDIATION_EFFORT_KEY, 12L + 42L);
+
+ assertMeasure(PROJECT, SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, 10L + 30L);
+ assertMeasure(PROJECT, SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, 8L + 38L);
+ assertMeasure(PROJECT, SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, 12L + 42L);
}
@Test
- public void sum_characteristic_measures_of_issues_without_effort() {
+ void sum_characteristic_measures_of_issues_without_effort() {
underTest.beforeComponent(FILE);
- underTest.onIssue(FILE, newCodeSmellIssueWithoutEffort());
- underTest.onIssue(FILE, newBugIssueWithoutEffort());
- underTest.onIssue(FILE, newVulnerabilityIssueWithoutEffort());
+ underTest.onIssue(FILE, newMaintainabilityIssueWithoutEffort());
+ underTest.onIssue(FILE, newReliabilityIssueWithoutEffort());
+ underTest.onIssue(FILE, newSecurityIssueWithoutEffort());
underTest.afterComponent(FILE);
underTest.beforeComponent(PROJECT);
- underTest.onIssue(PROJECT, newCodeSmellIssueWithoutEffort());
+ underTest.onIssue(PROJECT, newMaintainabilityIssueWithoutEffort());
underTest.afterComponent(PROJECT);
assertMeasure(PROJECT, TECHNICAL_DEBT_KEY, 0L);
assertMeasure(PROJECT, RELIABILITY_REMEDIATION_EFFORT_KEY, 0L);
assertMeasure(PROJECT, SECURITY_REMEDIATION_EFFORT_KEY, 0L);
+
+ assertMeasure(PROJECT, SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, 0L);
+ assertMeasure(PROJECT, SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, 0L);
+ assertMeasure(PROJECT, SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, 0L);
}
private void assertMeasure(Component component, String metricKey, long expectedValue) {
assertThat(measureRepository.getAddedRawMeasure(component, metricKey).get().getLongValue()).isEqualTo(expectedValue);
}
- private static DefaultIssue newCodeSmellIssue(long effort) {
- return newCodeSmellIssueWithoutEffort().setEffort(Duration.create(effort)).setType(CODE_SMELL);
+ private static DefaultIssue newIssue(long effort, Map<SoftwareQuality, Severity> impacts) {
+ return newMaintainabilityIssueWithoutEffort().setEffort(Duration.create(effort)).replaceImpacts(impacts);
+ }
+
+ private static DefaultIssue newMaintainabilityIssue(long effort) {
+ return newMaintainabilityIssueWithoutEffort().setEffort(Duration.create(effort)).setType(CODE_SMELL).replaceImpacts(Map.of(MAINTAINABILITY, HIGH));
}
- private static DefaultIssue newBugIssue(long effort) {
- return newCodeSmellIssueWithoutEffort().setEffort(Duration.create(effort)).setType(BUG);
+ private static DefaultIssue newReliabilityIssue(long effort) {
+ return newMaintainabilityIssueWithoutEffort().setEffort(Duration.create(effort)).setType(BUG).replaceImpacts(Map.of(RELIABILITY, HIGH));
}
- private static DefaultIssue newVulnerabilityIssue(long effort) {
- return newCodeSmellIssueWithoutEffort().setEffort(Duration.create(effort)).setType(VULNERABILITY);
+ private static DefaultIssue newSecurityIssue(long effort) {
+ return newMaintainabilityIssueWithoutEffort().setEffort(Duration.create(effort)).setType(VULNERABILITY).replaceImpacts(Map.of(SECURITY, HIGH));
}
- private static DefaultIssue newCodeSmellIssueWithoutEffort() {
- return new DefaultIssue().setType(CODE_SMELL);
+ private static DefaultIssue newMaintainabilityIssueWithoutEffort() {
+ return new DefaultIssue().setType(CODE_SMELL).replaceImpacts(Map.of(MAINTAINABILITY, HIGH));
}
- private static DefaultIssue newBugIssueWithoutEffort() {
- return new DefaultIssue().setType(BUG);
+ private static DefaultIssue newReliabilityIssueWithoutEffort() {
+ return new DefaultIssue().setType(BUG).replaceImpacts(Map.of(RELIABILITY, HIGH));
}
- private static DefaultIssue newVulnerabilityIssueWithoutEffort() {
- return new DefaultIssue().setType(VULNERABILITY);
+ private static DefaultIssue newSecurityIssueWithoutEffort() {
+ return new DefaultIssue().setType(VULNERABILITY).replaceImpacts(Map.of(SECURITY, HIGH));
}
}
*/
package org.sonar.ce.task.projectanalysis.issue;
-import org.junit.Test;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.sonar.api.issue.impact.Severity;
+import org.sonar.api.issue.impact.SoftwareQuality;
import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.Duration;
import org.sonar.ce.task.projectanalysis.analysis.Branch;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
+import static org.sonar.api.issue.impact.Severity.HIGH;
+import static org.sonar.api.issue.impact.SoftwareQuality.MAINTAINABILITY;
+import static org.sonar.api.issue.impact.SoftwareQuality.RELIABILITY;
+import static org.sonar.api.issue.impact.SoftwareQuality.SECURITY;
import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_REMEDIATION_EFFORT;
import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_REMEDIATION_EFFORT_KEY;
import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT;
import static org.sonar.api.rules.RuleType.BUG;
import static org.sonar.api.rules.RuleType.CODE_SMELL;
import static org.sonar.api.rules.RuleType.VULNERABILITY;
-
-public class NewEffortAggregatorTest {
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT;
+import static org.sonar.server.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY;
+
+class NewEffortAggregatorTest {
private static final Component FILE = ReportComponent.builder(Component.Type.FILE, 1).setUuid("FILE").build();
private static final Component PROJECT = ReportComponent.builder(Component.Type.PROJECT, 2).addChildren(FILE).build();
- @org.junit.Rule
+ @RegisterExtension
public PeriodHolderRule periodsHolder = new PeriodHolderRule();
- @org.junit.Rule
+ @RegisterExtension
public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
.add(NEW_TECHNICAL_DEBT)
.add(NEW_RELIABILITY_REMEDIATION_EFFORT)
- .add(NEW_SECURITY_REMEDIATION_EFFORT);
- @org.junit.Rule
+ .add(NEW_SECURITY_REMEDIATION_EFFORT)
+ .add(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT)
+ .add(NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT)
+ .add(NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT);
+ @RegisterExtension
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create();
private final NewIssueClassifier newIssueClassifier = mock(NewIssueClassifier.class);
private final NewEffortAggregator underTest = new NewEffortAggregator(metricRepository, measureRepository, newIssueClassifier);
@Test
- public void sum_new_maintainability_effort_of_issues() {
+ void sum_new_maintainability_effort_of_issues() {
when(newIssueClassifier.isEnabled()).thenReturn(true);
when(newIssueClassifier.isNew(any(), any())).thenReturn(true);
- DefaultIssue unresolved1 = newCodeSmellIssue(10L);
+ DefaultIssue unresolved1 = newMaintainabilityIssue(10L);
DefaultIssue old1 = oldCodeSmellIssue(100L);
- DefaultIssue unresolved2 = newCodeSmellIssue(30L);
+ DefaultIssue unresolved2 = newMaintainabilityIssue(30L);
DefaultIssue old2 = oldCodeSmellIssue(300L);
- DefaultIssue unresolvedWithoutDebt = newCodeSmellIssueWithoutEffort();
- DefaultIssue resolved = newCodeSmellIssue(50L).setResolution(RESOLUTION_FIXED);
+ DefaultIssue unresolvedWithoutDebt = newMaintainabilityIssueWithoutEffort();
+ DefaultIssue resolved = newMaintainabilityIssue(50L).setResolution(RESOLUTION_FIXED);
underTest.beforeComponent(FILE);
underTest.onIssue(FILE, unresolved1);
underTest.afterComponent(FILE);
assertValue(FILE, NEW_TECHNICAL_DEBT_KEY, 10 + 30);
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, 10 + 30);
}
@Test
- public void new_maintainability_effort_is_only_computed_using_code_smell_issues() {
+ void sum_effort_when_multiple_impacts() {
when(newIssueClassifier.isEnabled()).thenReturn(true);
when(newIssueClassifier.isNew(any(), any())).thenReturn(true);
- DefaultIssue codeSmellIssue = newCodeSmellIssue(10);
+
+ DefaultIssue unresolved1 = createIssue(CODE_SMELL, List.of(MAINTAINABILITY, RELIABILITY, SECURITY), 10, true);
+ DefaultIssue unresolved2 = createIssue(CODE_SMELL, List.of(MAINTAINABILITY, RELIABILITY, SECURITY), 10, true);
+
+ underTest.beforeComponent(FILE);
+ underTest.onIssue(FILE, unresolved1);
+ underTest.onIssue(FILE, unresolved2);
+ underTest.afterComponent(FILE);
+
+ // total maintainability effort
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, 20);
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, 20);
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, 20);
+ }
+
+ @Test
+ void new_maintainability_effort_is_only_computed_using_maintainability_issues() {
+ when(newIssueClassifier.isEnabled()).thenReturn(true);
+ when(newIssueClassifier.isNew(any(), any())).thenReturn(true);
+ DefaultIssue codeSmellIssue = newMaintainabilityIssue(10);
DefaultIssue oldSmellIssue = oldCodeSmellIssue(100);
// Issues of type BUG and VULNERABILITY should be ignored
- DefaultIssue bugIssue = newBugIssue(15);
+ DefaultIssue bugIssue = newReliabilityIssue(15);
DefaultIssue oldBugIssue = oldBugIssue(150);
- DefaultIssue vulnerabilityIssue = newVulnerabilityIssue(12);
+ DefaultIssue vulnerabilityIssue = newSecurityIssue(12);
DefaultIssue oldVulnerabilityIssue = oldVulnerabilityIssue(120);
underTest.beforeComponent(FILE);
// Only effort of CODE SMELL issue is used
assertValue(FILE, NEW_TECHNICAL_DEBT_KEY, 10);
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, 10);
}
@Test
- public void sum_new_reliability_effort_of_issues() {
+ void sum_new_reliability_effort_of_issues() {
when(newIssueClassifier.isEnabled()).thenReturn(true);
when(newIssueClassifier.isNew(any(), any())).thenReturn(true);
- DefaultIssue unresolved1 = newBugIssue(10L);
+ DefaultIssue unresolved1 = newReliabilityIssue(10L);
DefaultIssue old1 = oldBugIssue(100L);
- DefaultIssue unresolved2 = newBugIssue(30L);
+ DefaultIssue unresolved2 = newReliabilityIssue(30L);
DefaultIssue old2 = oldBugIssue(300L);
- DefaultIssue unresolvedWithoutDebt = newBugIssueWithoutEffort();
- DefaultIssue resolved = newBugIssue(50L).setResolution(RESOLUTION_FIXED);
+ DefaultIssue unresolvedWithoutDebt = newReliabilityIssueWithoutEffort();
+ DefaultIssue resolved = newReliabilityIssue(50L).setResolution(RESOLUTION_FIXED);
underTest.beforeComponent(FILE);
underTest.onIssue(FILE, unresolved1);
underTest.afterComponent(FILE);
assertValue(FILE, NEW_RELIABILITY_REMEDIATION_EFFORT_KEY, 10 + 30);
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, 10 + 30);
}
@Test
- public void new_reliability_effort_is_only_computed_using_bug_issues() {
+ void new_reliability_effort_is_only_computed_using_bug_issues() {
when(newIssueClassifier.isEnabled()).thenReturn(true);
when(newIssueClassifier.isNew(any(), any())).thenReturn(true);
- DefaultIssue bugIssue = newBugIssue(15);
+ DefaultIssue bugIssue = newReliabilityIssue(15);
DefaultIssue oldBugIssue = oldBugIssue(150);
// Issues of type CODE SMELL and VULNERABILITY should be ignored
- DefaultIssue codeSmellIssue = newCodeSmellIssue(10);
+ DefaultIssue codeSmellIssue = newMaintainabilityIssue(10);
DefaultIssue oldCodeSmellIssue = oldCodeSmellIssue(100);
- DefaultIssue vulnerabilityIssue = newVulnerabilityIssue(12);
+ DefaultIssue vulnerabilityIssue = newSecurityIssue(12);
DefaultIssue oldVulnerabilityIssue = oldVulnerabilityIssue(120);
underTest.beforeComponent(FILE);
// Only effort of BUG issue is used
assertValue(FILE, NEW_RELIABILITY_REMEDIATION_EFFORT_KEY, 15);
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, 15);
}
@Test
- public void sum_new_vulnerability_effort_of_issues() {
+ void sum_new_vulnerability_effort_of_issues() {
when(newIssueClassifier.isEnabled()).thenReturn(true);
- DefaultIssue unresolved1 = newVulnerabilityIssue(10L);
+ DefaultIssue unresolved1 = newSecurityIssue(10L);
DefaultIssue old1 = oldVulnerabilityIssue(100L);
- DefaultIssue unresolved2 = newVulnerabilityIssue(30L);
+ DefaultIssue unresolved2 = newSecurityIssue(30L);
DefaultIssue old2 = oldVulnerabilityIssue(300L);
- DefaultIssue unresolvedWithoutDebt = newVulnerabilityIssueWithoutEffort();
- DefaultIssue resolved = newVulnerabilityIssue(50L).setResolution(RESOLUTION_FIXED);
+ DefaultIssue unresolvedWithoutDebt = newSecurityIssueWithoutEffort();
+ DefaultIssue resolved = newSecurityIssue(50L).setResolution(RESOLUTION_FIXED);
DefaultIssue oldResolved = oldVulnerabilityIssue(500L).setResolution(RESOLUTION_FIXED);
underTest.beforeComponent(FILE);
underTest.afterComponent(FILE);
assertValue(FILE, NEW_SECURITY_REMEDIATION_EFFORT_KEY, 10 + 30);
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, 10 + 30);
}
@Test
- public void new_security_effort_is_only_computed_using_vulnerability_issues() {
+ void new_security_effort_is_only_computed_using_vulnerability_issues() {
when(newIssueClassifier.isEnabled()).thenReturn(true);
when(newIssueClassifier.isNew(any(), any())).thenReturn(true);
- DefaultIssue vulnerabilityIssue = newVulnerabilityIssue(12);
+ DefaultIssue vulnerabilityIssue = newSecurityIssue(12);
DefaultIssue oldVulnerabilityIssue = oldVulnerabilityIssue(120);
// Issues of type CODE SMELL and BUG should be ignored
- DefaultIssue codeSmellIssue = newCodeSmellIssue(10);
+ DefaultIssue codeSmellIssue = newMaintainabilityIssue(10);
DefaultIssue oldCodeSmellIssue = oldCodeSmellIssue(100);
- DefaultIssue bugIssue = newBugIssue(15);
+ DefaultIssue bugIssue = newReliabilityIssue(15);
DefaultIssue oldBugIssue = oldBugIssue(150);
underTest.beforeComponent(FILE);
// Only effort of VULNERABILITY issue is used
assertValue(FILE, NEW_SECURITY_REMEDIATION_EFFORT_KEY, 12);
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, 12);
}
@Test
- public void aggregate_new_characteristic_measures_of_children() {
+ void aggregate_new_characteristic_measures_of_children() {
when(newIssueClassifier.isEnabled()).thenReturn(true);
when(newIssueClassifier.isNew(any(), any())).thenReturn(true);
- DefaultIssue codeSmellIssue = newCodeSmellIssue(10);
+ DefaultIssue codeSmellIssue = newMaintainabilityIssue(10);
DefaultIssue oldCodeSmellIssue = oldCodeSmellIssue(100);
- DefaultIssue bugIssue = newBugIssue(8);
+ DefaultIssue bugIssue = newReliabilityIssue(8);
DefaultIssue oldBugIssue = oldBugIssue(80);
- DefaultIssue vulnerabilityIssue = newVulnerabilityIssue(12);
+ DefaultIssue vulnerabilityIssue = newSecurityIssue(12);
DefaultIssue oldVulnerabilityIssue = oldVulnerabilityIssue(120);
- DefaultIssue codeSmellProjectIssue = newCodeSmellIssue(30);
+ DefaultIssue codeSmellProjectIssue = newMaintainabilityIssue(30);
DefaultIssue oldCodeSmellProjectIssue = oldCodeSmellIssue(300);
- DefaultIssue bugProjectIssue = newBugIssue(28);
+ DefaultIssue bugProjectIssue = newReliabilityIssue(28);
DefaultIssue oldBugProjectIssue = oldBugIssue(280);
- DefaultIssue vulnerabilityProjectIssue = newVulnerabilityIssue(32);
+ DefaultIssue vulnerabilityProjectIssue = newSecurityIssue(32);
DefaultIssue oldVulnerabilityProjectIssue = oldVulnerabilityIssue(320);
underTest.beforeComponent(FILE);
assertValue(PROJECT, NEW_TECHNICAL_DEBT_KEY, 10 + 30);
assertValue(PROJECT, NEW_RELIABILITY_REMEDIATION_EFFORT_KEY, 8 + 28);
assertValue(PROJECT, NEW_SECURITY_REMEDIATION_EFFORT_KEY, 12 + 32);
+
+ assertValue(PROJECT, NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, 10 + 30);
+ assertValue(PROJECT, NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, 8 + 28);
+ assertValue(PROJECT, NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, 12 + 32);
}
@Test
- public void no_measures_if_no_periods() {
+ void no_measures_if_no_periods() {
when(newIssueClassifier.isEnabled()).thenReturn(false);
Branch branch = mock(Branch.class);
when(branch.getType()).thenReturn(BranchType.BRANCH);
periodsHolder.setPeriod(null);
- DefaultIssue unresolved = newCodeSmellIssue(10);
+ DefaultIssue unresolved = newMaintainabilityIssue(10);
underTest.beforeComponent(FILE);
underTest.onIssue(FILE, unresolved);
}
@Test
- public void should_have_empty_measures_if_no_issues() {
+ void should_have_empty_measures_if_no_issues() {
when(newIssueClassifier.isEnabled()).thenReturn(true);
when(newIssueClassifier.isNew(any(), any())).thenReturn(true);
assertValue(FILE, NEW_TECHNICAL_DEBT_KEY, 0);
assertValue(FILE, NEW_RELIABILITY_REMEDIATION_EFFORT_KEY, 0);
assertValue(FILE, NEW_SECURITY_REMEDIATION_EFFORT_KEY, 0);
+
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, 0);
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, 0);
+ assertValue(FILE, NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, 0);
}
private void assertValue(Component component, String metricKey, int value) {
assertThat(newMeasure.getLongValue()).isEqualTo(value);
}
- private DefaultIssue newCodeSmellIssue(long effort) {
- return createIssue(CODE_SMELL, effort, true);
+ private DefaultIssue newMaintainabilityIssue(long effort) {
+ return createIssue(CODE_SMELL, MAINTAINABILITY, effort, true);
}
private DefaultIssue oldCodeSmellIssue(long effort) {
- return createIssue(CODE_SMELL, effort, false);
+ return createIssue(CODE_SMELL, MAINTAINABILITY, effort, false);
}
- private DefaultIssue newBugIssue(long effort) {
- return createIssue(BUG, effort, true);
+ private DefaultIssue newReliabilityIssue(long effort) {
+ return createIssue(BUG, RELIABILITY, effort, true);
}
private DefaultIssue oldBugIssue(long effort) {
- return createIssue(BUG, effort, false);
+ return createIssue(BUG, RELIABILITY, effort, false);
}
- private DefaultIssue newVulnerabilityIssue(long effort) {
- return createIssue(VULNERABILITY, effort, true);
+ private DefaultIssue newSecurityIssue(long effort) {
+ return createIssue(VULNERABILITY, SECURITY, effort, true);
}
private DefaultIssue oldVulnerabilityIssue(long effort) {
- return createIssue(VULNERABILITY, effort, false);
+ return createIssue(VULNERABILITY, SECURITY, effort, false);
}
- private DefaultIssue newCodeSmellIssueWithoutEffort() {
+ private DefaultIssue newMaintainabilityIssueWithoutEffort() {
DefaultIssue defaultIssue = new DefaultIssue()
.setKey(UuidFactoryFast.getInstance().create())
+ .replaceImpacts(Map.of(MAINTAINABILITY, Severity.HIGH))
.setType(CODE_SMELL);
when(newIssueClassifier.isNew(any(), eq(defaultIssue))).thenReturn(true);
return defaultIssue;
}
- private DefaultIssue createIssue(RuleType type, long effort, boolean isNew) {
+ private DefaultIssue createIssue(RuleType type, SoftwareQuality softwareQuality, long effort, boolean isNew) {
+ return createIssue(type, List.of(softwareQuality), effort, isNew);
+ }
+
+ private DefaultIssue createIssue(RuleType type, List<SoftwareQuality> softwareQualities, long effort, boolean isNew) {
DefaultIssue defaultIssue = new DefaultIssue()
.setKey(UuidFactoryFast.getInstance().create())
.setEffort(Duration.create(effort))
- .setType(type);
+ .setType(type)
+ .replaceImpacts(softwareQualities.stream().collect(Collectors.toMap(e -> e, e -> HIGH)));
when(newIssueClassifier.isNew(any(), eq(defaultIssue))).thenReturn(isNew);
return defaultIssue;
}
- private static DefaultIssue newBugIssueWithoutEffort() {
- return new DefaultIssue().setType(BUG);
+ private static DefaultIssue newReliabilityIssueWithoutEffort() {
+ return new DefaultIssue().setType(BUG).replaceImpacts(Map.of(RELIABILITY, Severity.HIGH));
}
- private static DefaultIssue newVulnerabilityIssueWithoutEffort() {
- return new DefaultIssue().setType(VULNERABILITY);
+ private static DefaultIssue newSecurityIssueWithoutEffort() {
+ return new DefaultIssue().setType(VULNERABILITY).replaceImpacts(Map.of(SECURITY, Severity.HIGH));
}
}
public static final String SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY = "software_quality_reliability_remediation_effort";
- public static final Metric<Long> RELIABILITY_REMEDIATION_EFFORT =
+ public static final Metric<Long> SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT =
new Metric.Builder(SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, "Software Quality Reliability Remediation Effort",
Metric.ValueType.WORK_DUR)
.setDescription("Software quality reliability remediation effort")
NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT,
SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT,
NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT,
- RELIABILITY_REMEDIATION_EFFORT,
+ SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT,
NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT,
SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO,
NEW_SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT,
- SoftwareQualitiesMetrics.RELIABILITY_REMEDIATION_EFFORT,
+ SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO);