import java.util.HashMap;
import java.util.Map;
-import java.util.Set;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.metric.Metric;
import org.sonar.server.computation.metric.MetricRepository;
-import static com.google.common.collect.Maps.newHashMap;
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;
*/
public class EffortAggregator extends IssueVisitor {
- private final RuleRepository ruleRepository;
private final MeasureRepository measureRepository;
private final Metric maintainabilityEffortMetric;
private final Map<Integer, EffortCounter> effortsByComponentRef = new HashMap<>();
private EffortCounter effortCounter;
- public EffortAggregator(RuleRepository ruleRepository,
- MetricRepository metricRepository, MeasureRepository measureRepository) {
- this.ruleRepository = ruleRepository;
+ public EffortAggregator(MetricRepository metricRepository, MeasureRepository measureRepository) {
this.measureRepository = measureRepository;
this.maintainabilityEffortMetric = metricRepository.getByKey(TECHNICAL_DEBT_KEY);
this.reliabilityEffortMetric = metricRepository.getByKey(RELIABILITY_REMEDIATION_EFFORT_KEY);
this.effortCounter = null;
}
- private void computeMaintainabilityEffortMeasure(Component component){
- // total value
+ private void computeMaintainabilityEffortMeasure(Component component) {
measureRepository.add(component, maintainabilityEffortMetric, Measure.newMeasureBuilder().create(effortCounter.maintainabilityEffort));
-
- // TODO delete following lines when working on SONAR-7425
- // distribution by rule
- for (Map.Entry<Integer, Long> entry : effortCounter.maintainabilityEffortByRuleId.entrySet()) {
- int ruleId = entry.getKey();
- long ruleDebt = entry.getValue();
- // debt can't be zero.
- measureRepository.add(component, maintainabilityEffortMetric, Measure.newMeasureBuilder().forRule(ruleId).create(ruleDebt));
- }
}
- private void computeReliabilityEffortMeasure(Component component){
- // total value
+ private void computeReliabilityEffortMeasure(Component component) {
measureRepository.add(component, reliabilityEffortMetric, Measure.newMeasureBuilder().create(effortCounter.reliabilityEffort));
}
- private void computeSecurityEffortMeasure(Component component){
- // total value
+ private void computeSecurityEffortMeasure(Component component) {
measureRepository.add(component, securityEffortMetric, Measure.newMeasureBuilder().create(effortCounter.securityEffort));
}
private class EffortCounter {
private long maintainabilityEffort = 0L;
- private final SumMap<Integer> maintainabilityEffortByRuleId = new SumMap<>();
private long reliabilityEffort = 0L;
private long securityEffort = 0L;
Long issueEffort = issue.effortInMinutes();
if (issueEffort != null && issueEffort != 0L) {
switch (issue.type()) {
- case CODE_SMELL :
+ case CODE_SMELL:
maintainabilityEffort += issueEffort;
- Rule rule = ruleRepository.getByKey(issue.ruleKey());
- maintainabilityEffortByRuleId.add(rule.getId(), issueEffort);
break;
case BUG:
reliabilityEffort += issueEffort;
public void add(EffortCounter effortCounter) {
maintainabilityEffort += effortCounter.maintainabilityEffort;
- maintainabilityEffortByRuleId.add(effortCounter.maintainabilityEffortByRuleId);
reliabilityEffort += effortCounter.reliabilityEffort;
securityEffort += effortCounter.securityEffort;
}
}
-
- private static class SumMap<E> {
- private final Map<E, Long> sumByKeys = newHashMap();
-
- void add(SumMap<E> other) {
- for (Map.Entry<E, Long> entry : other.entrySet()) {
- add(entry.getKey(), entry.getValue());
- }
- }
-
- void add(@Nullable E key, Long value) {
- if (key != null) {
- Long currentValue = sumByKeys.get(key);
- sumByKeys.put(key, currentValue != null ? (currentValue + value) : value);
- }
- }
-
- @CheckForNull
- Long get(E key) {
- return sumByKeys.get(key);
- }
-
- Set<Map.Entry<E, Long>> entrySet() {
- return sumByKeys.entrySet();
- }
- }
}
import org.sonar.server.computation.metric.MetricRepositoryRule;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.guava.api.Assertions.assertThat;
import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
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.rules.RuleType.BUG;
import static org.sonar.api.rules.RuleType.CODE_SMELL;
import static org.sonar.api.rules.RuleType.VULNERABILITY;
-import static org.sonar.db.rule.RuleTesting.XOO_X1;
public 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();
- static final DumbRule RULE = new DumbRule(XOO_X1).setId(100);
-
- @org.junit.Rule
- public RuleRepositoryRule ruleRepository = new RuleRepositoryRule().add(RULE);
-
@org.junit.Rule
public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
.add(TECHNICAL_DEBT)
@org.junit.Rule
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(PROJECT, metricRepository);
- EffortAggregator underTest = new EffortAggregator(ruleRepository, metricRepository, measureRepository);
+ EffortAggregator underTest = new EffortAggregator(metricRepository, measureRepository);
@Test
public void sum_maintainability_effort_of_unresolved_issues() {
// total maintainability effort
assertMeasure(FILE, TECHNICAL_DEBT_KEY, 10L + 30L);
-
- // maintainability effort by rule
- assertMaintainabilityRuleMeasure(FILE, RULE, 10L + 30L);
}
@Test
assertMeasure(PROJECT, TECHNICAL_DEBT_KEY, 10L + 30L);
assertMeasure(PROJECT, RELIABILITY_REMEDIATION_EFFORT_KEY, 8L + 38L);
assertMeasure(PROJECT, SECURITY_REMEDIATION_EFFORT_KEY, 12L + 42L);
-
- // maintainability effort by rule
- assertMaintainabilityRuleMeasure(PROJECT, RULE, 10L + 30L);
}
@Test
assertMeasure(PROJECT, TECHNICAL_DEBT_KEY, 0L);
assertMeasure(PROJECT, RELIABILITY_REMEDIATION_EFFORT_KEY, 0L);
assertMeasure(PROJECT, SECURITY_REMEDIATION_EFFORT_KEY, 0L);
-
- // maintainability effort by rule
- assertThat(measureRepository.getAddedRawRuleMeasure(PROJECT, TECHNICAL_DEBT_KEY, RULE.getId())).isAbsent();
}
private void assertMeasure(Component component, String metricKey, long expectedValue) {
assertThat(measureRepository.getAddedRawMeasure(component, metricKey).get().getLongValue()).isEqualTo(expectedValue);
}
- private void assertMaintainabilityRuleMeasure(Component component, Rule rule, long expectedValue) {
- assertThat(measureRepository.getAddedRawRuleMeasure(component, TECHNICAL_DEBT_KEY, rule.getId()).get().getLongValue()).isEqualTo(expectedValue);
- }
-
private static DefaultIssue newCodeSmellIssue(long effort) {
return newCodeSmellIssueWithoutEffort().setEffort(Duration.create(effort)).setType(CODE_SMELL);
}
}
private static DefaultIssue newCodeSmellIssueWithoutEffort() {
- return new DefaultIssue().setRuleKey(RULE.getKey()).setType(CODE_SMELL);
+ return new DefaultIssue().setType(CODE_SMELL);
}
private static DefaultIssue newBugIssueWithoutEffort() {
- return new DefaultIssue().setRuleKey(RULE.getKey()).setType(BUG);
+ return new DefaultIssue().setType(BUG);
}
private static DefaultIssue newVulnerabilityIssueWithoutEffort() {
- return new DefaultIssue().setRuleKey(RULE.getKey()).setType(VULNERABILITY);
+ return new DefaultIssue().setType(VULNERABILITY);
}
}