diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2018-08-14 13:39:54 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2018-09-19 10:51:39 +0200 |
commit | 500ded18cf93bccab83dd94e8b3f74302114d5d2 (patch) | |
tree | 413f75aad896c4e8da0c9486625643976aa7424d /server/sonar-ce-task-projectanalysis | |
parent | f2dbe93832ced5dd2a2edea0cb465c001ffbbd01 (diff) | |
download | sonarqube-500ded18cf93bccab83dd94e8b3f74302114d5d2.tar.gz sonarqube-500ded18cf93bccab83dd94e8b3f74302114d5d2.zip |
SONAR-11151 Use changed lines in the Scanner report to calculate metrics concerning new code
Diffstat (limited to 'server/sonar-ce-task-projectanalysis')
26 files changed, 382 insertions, 562 deletions
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java index 55b2be91c70..39911cc9047 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java @@ -112,6 +112,7 @@ import org.sonar.ce.task.projectanalysis.scm.ScmInfoDbLoader; import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryImpl; import org.sonar.ce.task.projectanalysis.source.DbLineHashVersion; import org.sonar.ce.task.projectanalysis.source.LastCommitVisitor; +import org.sonar.ce.task.projectanalysis.source.NewLinesRepository; import org.sonar.ce.task.projectanalysis.source.SignificantCodeRepository; import org.sonar.ce.task.projectanalysis.source.SourceHashRepositoryImpl; import org.sonar.ce.task.projectanalysis.source.SourceLinesDiffImpl; @@ -205,6 +206,7 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop DbLineHashVersion.class, SignificantCodeRepository.class, SourceLinesHashCache.class, + NewLinesRepository.class, // issues RuleRepositoryImpl.class, diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/CounterInitializationContext.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/CounterInitializationContext.java index febac2da9a0..f952bf15ca9 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/CounterInitializationContext.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/CounterInitializationContext.java @@ -21,10 +21,7 @@ package org.sonar.ce.task.projectanalysis.formula; import com.google.common.base.Optional; import org.sonar.ce.task.projectanalysis.component.Component; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.measure.Measure; -import org.sonar.ce.task.projectanalysis.period.Period; /** * The context passing information to {@link Counter#initialize(CounterInitializationContext)}. @@ -41,14 +38,4 @@ public interface CounterInitializationContext { */ Optional<Measure> getMeasure(String metricKey); - /** - * Return Period defined for the current project. It can be used to retrieve variation Measure. - */ - Period getPeriod(); - - /** - * Finds out whether the a period is definfed or not - */ - boolean hasPeriod(); - } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/CreateMeasureContext.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/CreateMeasureContext.java index ce626a1d9bc..0af44936204 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/CreateMeasureContext.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/CreateMeasureContext.java @@ -21,10 +21,6 @@ package org.sonar.ce.task.projectanalysis.formula; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.component.Component; -import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.ce.task.projectanalysis.period.Period; /** * Context passing information to implementation of {@link Formula#createMeasure(Counter, CreateMeasureContext)} method. @@ -40,13 +36,4 @@ public interface CreateMeasureContext { */ Metric getMetric(); - /** - * The period for which variation of the measure can be created. - */ - Period getPeriod(); - - /** - * Finds out whether the a period is definfed or not - */ - boolean hasPeriod(); } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/FormulaExecutorComponentVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/FormulaExecutorComponentVisitor.java index 84f5a910541..5cd56d37652 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/FormulaExecutorComponentVisitor.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/FormulaExecutorComponentVisitor.java @@ -30,18 +30,10 @@ import org.sonar.ce.task.projectanalysis.component.ComponentVisitor; import org.sonar.ce.task.projectanalysis.component.PathAwareVisitorAdapter; import org.sonar.ce.task.projectanalysis.metric.Metric; import org.sonar.ce.task.projectanalysis.metric.MetricRepository; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolder; -import org.sonar.ce.task.projectanalysis.component.Component; -import org.sonar.ce.task.projectanalysis.component.ComponentVisitor; import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit; -import org.sonar.ce.task.projectanalysis.component.PathAwareVisitorAdapter; import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; -import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.ce.task.projectanalysis.metric.MetricRepository; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolder; + import static java.util.Objects.requireNonNull; @@ -66,15 +58,12 @@ public class FormulaExecutorComponentVisitor extends PathAwareVisitorAdapter<For } }; - @CheckForNull - private final PeriodHolder periodHolder; private final MetricRepository metricRepository; private final MeasureRepository measureRepository; private final List<Formula> formulas; private FormulaExecutorComponentVisitor(Builder builder, Iterable<Formula> formulas) { super(CrawlerDepthLimit.LEAVES, ComponentVisitor.Order.POST_ORDER, COUNTERS_FACTORY); - this.periodHolder = builder.periodHolder; this.measureRepository = builder.measureRepository; this.metricRepository = builder.metricRepository; this.formulas = ImmutableList.copyOf(formulas); @@ -87,8 +76,6 @@ public class FormulaExecutorComponentVisitor extends PathAwareVisitorAdapter<For public static class Builder { private final MetricRepository metricRepository; private final MeasureRepository measureRepository; - @CheckForNull - private PeriodHolder periodHolder; private Builder(MetricRepository metricRepository, MeasureRepository measureRepository) { this.metricRepository = requireNonNull(metricRepository); @@ -99,11 +86,6 @@ public class FormulaExecutorComponentVisitor extends PathAwareVisitorAdapter<For return new Builder(metricRepository, measureRepository); } - public Builder withVariationSupport(PeriodHolder periodHolder) { - this.periodHolder = requireNonNull(periodHolder); - return this; - } - public FormulaExecutorComponentVisitor buildFor(Iterable<Formula> formulas) { return new FormulaExecutorComponentVisitor(this, formulas); } @@ -212,15 +194,6 @@ public class FormulaExecutorComponentVisitor extends PathAwareVisitorAdapter<For return measureRepository.getRawMeasure(file, metricRepository.getByKey(metricKey)); } - @Override - public Period getPeriod() { - return periodHolder.getPeriod(); - } - - @Override - public boolean hasPeriod() { - return periodHolder.hasPeriod(); - } } public static class Counters { @@ -263,14 +236,5 @@ public class FormulaExecutorComponentVisitor extends PathAwareVisitorAdapter<For return metric; } - @Override - public Period getPeriod() { - return periodHolder.getPeriod(); - } - - @Override - public boolean hasPeriod() { - return periodHolder.hasPeriod(); - } } } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewEffortAggregator.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewEffortAggregator.java index 7c7f9e0473f..acb3e519863 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewEffortAggregator.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewEffortAggregator.java @@ -25,7 +25,6 @@ import java.util.Map; import org.sonar.api.measures.CoreMetrics; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.core.issue.DefaultIssue; -import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; import org.sonar.ce.task.projectanalysis.metric.Metric; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/period/PeriodHolder.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/period/PeriodHolder.java index 937d8ce874d..ba7d733c79a 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/period/PeriodHolder.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/period/PeriodHolder.java @@ -19,6 +19,8 @@ */ package org.sonar.ce.task.projectanalysis.period; +import javax.annotation.CheckForNull; + /** * Repository of period used to compute differential measures. * Here are the steps to retrieve the period : @@ -40,6 +42,7 @@ public interface PeriodHolder { * * @throws IllegalStateException if the periods haven't been initialized */ + @CheckForNull Period getPeriod(); } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java index e4be7a7294b..2fed329b51a 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java @@ -21,6 +21,7 @@ package org.sonar.ce.task.projectanalysis.qualitymodel; import com.google.common.base.Optional; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.utils.KeyValueFormat; @@ -35,11 +36,7 @@ import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; import org.sonar.ce.task.projectanalysis.metric.Metric; import org.sonar.ce.task.projectanalysis.metric.MetricRepository; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolder; -import org.sonar.ce.task.projectanalysis.scm.Changeset; -import org.sonar.ce.task.projectanalysis.scm.ScmInfo; -import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepository; +import org.sonar.ce.task.projectanalysis.source.NewLinesRepository; import static org.sonar.api.measures.CoreMetrics.NCLOC_DATA_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_DEVELOPMENT_COST_KEY; @@ -61,9 +58,8 @@ import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilde public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<NewMaintainabilityMeasuresVisitor.Counter> { private static final Logger LOG = Loggers.get(NewMaintainabilityMeasuresVisitor.class); - private final ScmInfoRepository scmInfoRepository; private final MeasureRepository measureRepository; - private final PeriodHolder periodHolder; + private final NewLinesRepository newLinesRepository; private final RatingSettings ratingSettings; private final Metric newDebtMetric; @@ -73,12 +69,11 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N private final Metric newDebtRatioMetric; private final Metric newMaintainabilityRatingMetric; - public NewMaintainabilityMeasuresVisitor(MetricRepository metricRepository, MeasureRepository measureRepository, ScmInfoRepository scmInfoRepository, - PeriodHolder periodHolder, RatingSettings ratingSettings) { + public NewMaintainabilityMeasuresVisitor(MetricRepository metricRepository, MeasureRepository measureRepository, NewLinesRepository newLinesRepository, + RatingSettings ratingSettings) { super(CrawlerDepthLimit.FILE, POST_ORDER, CounterFactory.INSTANCE); this.measureRepository = measureRepository; - this.scmInfoRepository = scmInfoRepository; - this.periodHolder = periodHolder; + this.newLinesRepository = newLinesRepository; this.ratingSettings = ratingSettings; // computed by NewDebtAggregator which is executed by IntegrateIssuesVisitor @@ -117,7 +112,7 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N } private void computeAndSaveNewDebtRatioMeasure(Component component, Path<Counter> path) { - if (!periodHolder.hasPeriod()) { + if (!newLinesRepository.newLinesAvailable()) { return; } double density = computeDensity(path.current()); @@ -156,37 +151,33 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N private void initNewDebtRatioCounter(Component file, Path<Counter> path) { // first analysis, no period, no differential value to compute, save processing time and return now - if (!periodHolder.hasPeriod()) { + if (!newLinesRepository.newLinesAvailable()) { return; } - Optional<Measure> nclocDataMeasure = measureRepository.getRawMeasure(file, this.nclocDataMetric); - if (!nclocDataMeasure.isPresent()) { + java.util.Optional<Set<Integer>> changedLines = newLinesRepository.getNewLines(file); + + if (!changedLines.isPresent()) { + LOG.trace(String.format("No information about changed lines is available for file '%s'. Dev cost will be zero.", file.getKey())); return; } - java.util.Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(file); - if (!scmInfoOptional.isPresent()) { - LOG.trace(String.format("No changeset for file %s. Dev cost will be zero.", file.getKey())); + Optional<Measure> nclocDataMeasure = measureRepository.getRawMeasure(file, this.nclocDataMetric); + if (!nclocDataMeasure.isPresent()) { return; } - ScmInfo scmInfo = scmInfoOptional.get(); - initNewDebtRatioCounter(path.current(), file, nclocDataMeasure.get(), scmInfo); + initNewDebtRatioCounter(path.current(), file, nclocDataMeasure.get(), changedLines.get()); } - private void initNewDebtRatioCounter(Counter devCostCounter, Component file, Measure nclocDataMeasure, ScmInfo scmInfo) { + private void initNewDebtRatioCounter(Counter devCostCounter, Component file, Measure nclocDataMeasure, Set<Integer> changedLines) { boolean hasDevCost = false; long lineDevCost = ratingSettings.getDevCost(file.getFileAttributes().getLanguageKey()); for (Integer nclocLineIndex : nclocLineIndexes(nclocDataMeasure)) { - if (scmInfo.hasChangesetForLine(nclocLineIndex)) { - Changeset changeset = scmInfo.getChangesetForLine(nclocLineIndex); - Period period = periodHolder.getPeriod(); - if (isLineInPeriod(changeset.getDate(), period)) { - devCostCounter.incrementDevCost(lineDevCost); - hasDevCost = true; - } + if (changedLines.contains(nclocLineIndex)) { + devCostCounter.incrementDevCost(lineDevCost); + hasDevCost = true; } } if (hasDevCost) { @@ -200,13 +191,6 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N } /** - * A line belongs to a Period if its date is older than the SNAPSHOT's date of the period. - */ - private static boolean isLineInPeriod(long lineDate, Period period) { - return lineDate > period.getSnapshotDate(); - } - - /** * NCLOC_DATA contains Key-value pairs, where key - is a number of line, and value - is an indicator of whether line * contains code (1) or not (0). * diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepository.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepository.java index 605815b5083..cd4c2d187ba 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepository.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepository.java @@ -21,7 +21,6 @@ package org.sonar.ce.task.projectanalysis.scm; import java.util.Optional; import org.sonar.ce.task.projectanalysis.component.Component; -import org.sonar.ce.task.projectanalysis.component.Component; /** * Return SCM information of components. @@ -33,10 +32,10 @@ public interface ScmInfoRepository { /** * Returns Scm info for the specified component if there is any, first looking into the report, then into the database * <p> - * If there's nothing in the report and in the db (on first analysis for instance), then it return a {@link Optional#absent()}. + * If there's nothing in the report and in the db (on first analysis for instance), then it return a {@link Optional#empty()}. * </p> * <p> - * This method will always return {@link Optional#absent()} if the specified component's type is not {@link Component.Type#FILE}. + * This method will always return {@link Optional#empty()} if the specified component's type is not {@link Component.Type#FILE}. * </p> * * @throws NullPointerException if argument is {@code null} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/ComputeFileSourceData.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/ComputeFileSourceData.java index c492be64aee..37abda33162 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/ComputeFileSourceData.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/ComputeFileSourceData.java @@ -19,7 +19,6 @@ */ package org.sonar.ce.task.projectanalysis.source; -import com.google.common.base.Joiner; import java.util.Iterator; import java.util.List; import org.sonar.core.hash.SourceHashComputer; @@ -28,8 +27,6 @@ import org.sonar.ce.task.projectanalysis.source.SourceLinesHashRepositoryImpl.Li import org.sonar.ce.task.projectanalysis.source.linereader.LineReader; public class ComputeFileSourceData { - private static final Joiner LINE_RETURN_JOINER = Joiner.on('\n'); - private final List<LineReader> lineReaders; private final Iterator<String> linesIterator; private final SourceHashComputer sourceHashComputer; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepository.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepository.java index d2d0c9b562d..38e14292a97 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepository.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepository.java @@ -24,7 +24,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; -import javax.annotation.Nullable; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.ce.task.projectanalysis.batch.BatchReportReader; import org.sonar.ce.task.projectanalysis.component.Component; @@ -38,24 +37,18 @@ public class NewLinesRepository { private final BatchReportReader reportReader; private final AnalysisMetadataHolder analysisMetadataHolder; private final ScmInfoRepository scmInfoRepository; - @Nullable - private final Period period; + private final PeriodHolder periodHolder; private final Map<Component, Optional<Set<Integer>>> changedLinesCache = new HashMap<>(); public NewLinesRepository(BatchReportReader reportReader, AnalysisMetadataHolder analysisMetadataHolder, PeriodHolder periodHolder, ScmInfoRepository scmInfoRepository) { this.reportReader = reportReader; this.analysisMetadataHolder = analysisMetadataHolder; this.scmInfoRepository = scmInfoRepository; - this.period = periodHolder.getPeriod(); + this.periodHolder = periodHolder; } - public boolean newLinesAvailable(Component component) { - return getNewLines(component).isPresent(); - } - - public boolean isLineNew(Component component, int line) { - return getNewLines(component).map(s -> s.contains(line)) - .orElseThrow(() -> new IllegalStateException("No data about new lines available")); + public boolean newLinesAvailable() { + return periodHolder.hasPeriod(); } public Optional<Set<Integer>> getNewLines(Component component) { @@ -67,11 +60,16 @@ public class NewLinesRepository { if (reportChangedLines.isPresent()) { return reportChangedLines; } - return generateNewLinesFromScm(component); + return computeNewLinesFromScm(component); } - private Optional<Set<Integer>> generateNewLinesFromScm(Component component) { - if (period == null) { + /** + * If the changed lines are not in the report or if we are not analyzing a short lived branch (or P/R) we fall back to this method. + * If there is a period and SCM information, we compare the change dates of each line with the start of the period to figure out + * if a line is new or not. + */ + private Optional<Set<Integer>> computeNewLinesFromScm(Component component) { + if (!periodHolder.hasPeriod()) { return Optional.empty(); } @@ -85,7 +83,7 @@ public class NewLinesRepository { Set<Integer> lines = new HashSet<>(); for (Map.Entry<Integer, Changeset> e : allChangesets.entrySet()) { - if (isLineInPeriod(e.getValue().getDate(), period)) { + if (isLineInPeriod(e.getValue().getDate(), periodHolder.getPeriod())) { lines.add(e.getKey()); } } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/SignificantCodeRepository.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/SignificantCodeRepository.java index 64974bc273c..0138915b272 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/SignificantCodeRepository.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/SignificantCodeRepository.java @@ -25,7 +25,6 @@ import org.sonar.core.hash.LineRange; import org.sonar.core.util.CloseableIterator; import org.sonar.scanner.protocol.output.ScannerReport.LineSgnificantCode; import org.sonar.ce.task.projectanalysis.batch.BatchReportReader; -import org.sonar.ce.task.projectanalysis.component.Component; public class SignificantCodeRepository { private final BatchReportReader reportReader; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/NewCoverageMeasuresStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/NewCoverageMeasuresStep.java index 6048a183f24..ed00e29c933 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/NewCoverageMeasuresStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/NewCoverageMeasuresStep.java @@ -25,13 +25,12 @@ import com.google.common.collect.Iterables; import java.util.Collections; import java.util.List; import java.util.Map; -import javax.annotation.CheckForNull; +import java.util.Set; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import org.apache.commons.lang.ObjectUtils; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.utils.KeyValueFormat; -import org.sonar.ce.task.projectanalysis.batch.BatchReportReader; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.PathAwareCrawler; import org.sonar.ce.task.projectanalysis.component.TreeRootHolder; @@ -50,10 +49,7 @@ import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; import org.sonar.ce.task.projectanalysis.metric.Metric; import org.sonar.ce.task.projectanalysis.metric.MetricRepository; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolder; -import org.sonar.ce.task.projectanalysis.scm.ScmInfo; -import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepository; +import org.sonar.ce.task.projectanalysis.source.NewLinesRepository; import org.sonar.ce.task.step.ComputationStep; import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder; @@ -70,44 +66,39 @@ public class NewCoverageMeasuresStep implements ComputationStep { new NewLineCoverageFormula()); private final TreeRootHolder treeRootHolder; - private final PeriodHolder periodHolder; private final MetricRepository metricRepository; private final MeasureRepository measureRepository; - @CheckForNull - private final ScmInfoRepository scmInfoRepository; + @Nullable + private final NewLinesRepository newLinesRepository; /** - * Constructor used when processing a Report (ie. a {@link BatchReportReader} instance is available in the container) + * Constructor used when processing a Report (ie. a {@link NewLinesRepository} instance is available in the container) */ - public NewCoverageMeasuresStep(TreeRootHolder treeRootHolder, PeriodHolder periodHolder, - MeasureRepository measureRepository, final MetricRepository metricRepository, ScmInfoRepository scmInfoRepository) { + public NewCoverageMeasuresStep(TreeRootHolder treeRootHolder, + MeasureRepository measureRepository, MetricRepository metricRepository, NewLinesRepository newLinesRepository) { this.treeRootHolder = treeRootHolder; - this.periodHolder = periodHolder; this.metricRepository = metricRepository; this.measureRepository = measureRepository; - this.scmInfoRepository = scmInfoRepository; + this.newLinesRepository = newLinesRepository; } /** - * Constructor used when processing Views (ie. no {@link BatchReportReader} instance is available in the container) + * Constructor used when processing Views (ie. no {@link NewLinesRepository} instance is available in the container) */ - public NewCoverageMeasuresStep(TreeRootHolder treeRootHolder, PeriodHolder periodHolder, - MeasureRepository measureRepository, final MetricRepository metricRepository) { + public NewCoverageMeasuresStep(TreeRootHolder treeRootHolder, MeasureRepository measureRepository, MetricRepository metricRepository) { this.treeRootHolder = treeRootHolder; - this.periodHolder = periodHolder; this.metricRepository = metricRepository; this.measureRepository = measureRepository; - this.scmInfoRepository = null; + this.newLinesRepository = null; } @Override public void execute(ComputationStep.Context context) { new PathAwareCrawler<>( FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository) - .withVariationSupport(periodHolder) .buildFor( - Iterables.concat(NewLinesAndConditionsCoverageFormula.from(scmInfoRepository), FORMULAS))) - .visit(treeRootHolder.getRoot()); + Iterables.concat(NewLinesAndConditionsCoverageFormula.from(newLinesRepository), FORMULAS))) + .visit(treeRootHolder.getRoot()); } @Override @@ -122,18 +113,18 @@ public class NewCoverageMeasuresStep implements ComputationStep { CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY); private static final Iterable<Formula<?>> VIEWS_FORMULAS = variationSumFormulas(OUTPUT_METRIC_KEYS); - private NewLinesAndConditionsCoverageFormula(ScmInfoRepository scmInfoRepository) { - super(scmInfoRepository, + private NewLinesAndConditionsCoverageFormula(NewLinesRepository newLinesRepository) { + super(newLinesRepository, new NewCoverageInputMetricKeys( CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, CoreMetrics.CONDITIONS_BY_LINE_KEY, CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY), OUTPUT_METRIC_KEYS); } - public static Iterable<Formula<?>> from(@Nullable ScmInfoRepository scmInfoRepository) { - if (scmInfoRepository == null) { + public static Iterable<Formula<?>> from(@Nullable NewLinesRepository newLinesRepository) { + if (newLinesRepository == null) { return VIEWS_FORMULAS; } - return Collections.singleton(new NewLinesAndConditionsCoverageFormula(scmInfoRepository)); + return Collections.singleton(new NewLinesAndConditionsCoverageFormula(newLinesRepository)); } /** @@ -176,19 +167,19 @@ public class NewCoverageMeasuresStep implements ComputationStep { } public static class NewLinesAndConditionsFormula implements Formula<NewCoverageCounter> { - private final ScmInfoRepository scmInfoRepository; + private final NewLinesRepository newLinesRepository; private final NewCoverageInputMetricKeys inputMetricKeys; private final NewCoverageOutputMetricKeys outputMetricKeys; - public NewLinesAndConditionsFormula(ScmInfoRepository scmInfoRepository, NewCoverageInputMetricKeys inputMetricKeys, NewCoverageOutputMetricKeys outputMetricKeys) { - this.scmInfoRepository = scmInfoRepository; + public NewLinesAndConditionsFormula(NewLinesRepository newLinesRepository, NewCoverageInputMetricKeys inputMetricKeys, NewCoverageOutputMetricKeys outputMetricKeys) { + this.newLinesRepository = newLinesRepository; this.inputMetricKeys = inputMetricKeys; this.outputMetricKeys = outputMetricKeys; } @Override public NewCoverageCounter createNewCounter() { - return new NewCoverageCounter(scmInfoRepository, inputMetricKeys); + return new NewCoverageCounter(newLinesRepository, inputMetricKeys); } @Override @@ -232,11 +223,11 @@ public class NewCoverageMeasuresStep implements ComputationStep { private final IntValue newCoveredLines = new IntValue(); private final IntValue newConditions = new IntValue(); private final IntValue newCoveredConditions = new IntValue(); - private final ScmInfoRepository scmInfoRepository; + private final NewLinesRepository newLinesRepository; private final NewCoverageInputMetricKeys metricKeys; - public NewCoverageCounter(ScmInfoRepository scmInfoRepository, NewCoverageInputMetricKeys metricKeys) { - this.scmInfoRepository = scmInfoRepository; + public NewCoverageCounter(NewLinesRepository newLinesRepository, NewCoverageInputMetricKeys metricKeys) { + this.newLinesRepository = newLinesRepository; this.metricKeys = metricKeys; } @@ -251,11 +242,10 @@ public class NewCoverageMeasuresStep implements ComputationStep { @Override public void initialize(CounterInitializationContext context) { Component fileComponent = context.getLeaf(); - java.util.Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(fileComponent); - if (!scmInfoOptional.isPresent() || !context.hasPeriod()) { + java.util.Optional<Set<Integer>> newLinesSet = newLinesRepository.getNewLines(fileComponent); + if (!newLinesSet.isPresent()) { return; } - ScmInfo componentScm = scmInfoOptional.get(); newLines.increment(0); newCoveredLines.increment(0); @@ -272,9 +262,8 @@ public class NewCoverageMeasuresStep implements ComputationStep { int hits = entry.getValue(); int conditions = (Integer) ObjectUtils.defaultIfNull(conditionsByLine.get(lineId), 0); int coveredConditions = (Integer) ObjectUtils.defaultIfNull(coveredConditionsByLine.get(lineId), 0); - if (componentScm.hasChangesetForLine(lineId)) { - long date = componentScm.getChangesetForLine(lineId).getDate(); - analyze(context.getPeriod(), date, hits, conditions, coveredConditions); + if (newLinesSet.get().contains(lineId)) { + analyze(hits, conditions, coveredConditions); } } } @@ -286,18 +275,9 @@ public class NewCoverageMeasuresStep implements ComputationStep { return Collections.emptyMap(); } - void analyze(Period period, long lineDate, int hits, int conditions, int coveredConditions) { - if (isLineInPeriod(lineDate, period)) { - incrementLines(hits); - incrementConditions(conditions, coveredConditions); - } - } - - /** - * A line belongs to a Period if its date is older than the SNAPSHOT's date of the period. - */ - private static boolean isLineInPeriod(long lineDate, Period period) { - return lineDate > period.getSnapshotDate(); + void analyze(int hits, int conditions, int coveredConditions) { + incrementLines(hits); + incrementConditions(conditions, coveredConditions); } private void incrementLines(int hits) { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/NewSizeMeasuresStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/NewSizeMeasuresStep.java index c4abc14afd9..bc1b3c2f5b6 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/NewSizeMeasuresStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/NewSizeMeasuresStep.java @@ -40,11 +40,7 @@ import org.sonar.ce.task.projectanalysis.formula.counter.IntValue; import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; import org.sonar.ce.task.projectanalysis.metric.MetricRepository; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolder; -import org.sonar.ce.task.projectanalysis.scm.Changeset; -import org.sonar.ce.task.projectanalysis.scm.ScmInfo; -import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepository; +import org.sonar.ce.task.projectanalysis.source.NewLinesRepository; import org.sonar.ce.task.step.ComputationStep; import static org.sonar.api.measures.CoreMetrics.NEW_BLOCKS_DUPLICATED_KEY; @@ -58,18 +54,16 @@ import static org.sonar.api.measures.CoreMetrics.NEW_LINES_KEY; public class NewSizeMeasuresStep implements ComputationStep { private final TreeRootHolder treeRootHolder; - private final PeriodHolder periodHolder; private final MetricRepository metricRepository; private final MeasureRepository measureRepository; private final NewDuplicationFormula duplicationFormula; - public NewSizeMeasuresStep(TreeRootHolder treeRootHolder, PeriodHolder periodHolder, MetricRepository metricRepository, MeasureRepository measureRepository, - ScmInfoRepository scmInfoRepository, DuplicationRepository duplicationRepository) { + public NewSizeMeasuresStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository, + NewLinesRepository newLinesRepository, DuplicationRepository duplicationRepository) { this.treeRootHolder = treeRootHolder; - this.periodHolder = periodHolder; this.metricRepository = metricRepository; this.measureRepository = measureRepository; - this.duplicationFormula = new NewDuplicationFormula(scmInfoRepository, duplicationRepository); + this.duplicationFormula = new NewDuplicationFormula(newLinesRepository, duplicationRepository); } @Override @@ -81,22 +75,21 @@ public class NewSizeMeasuresStep implements ComputationStep { public void execute(ComputationStep.Context context) { new PathAwareCrawler<>( FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository) - .withVariationSupport(periodHolder) .buildFor(ImmutableList.of(duplicationFormula))) - .visit(treeRootHolder.getRoot()); + .visit(treeRootHolder.getRoot()); } private static class NewSizeCounter implements Counter<NewSizeCounter> { private final DuplicationRepository duplicationRepository; - private final ScmInfoRepository scmInfoRepository; + private final NewLinesRepository newLinesRepository; + private final IntValue newLines = new IntValue(); private final IntValue newDuplicatedLines = new IntValue(); private final IntValue newDuplicatedBlocks = new IntValue(); - private NewSizeCounter(DuplicationRepository duplicationRepository, - ScmInfoRepository scmInfoRepository) { + private NewSizeCounter(DuplicationRepository duplicationRepository, NewLinesRepository newLinesRepository) { this.duplicationRepository = duplicationRepository; - this.scmInfoRepository = scmInfoRepository; + this.newLinesRepository = newLinesRepository; } @Override @@ -109,8 +102,8 @@ public class NewSizeMeasuresStep implements ComputationStep { @Override public void initialize(CounterInitializationContext context) { Component leaf = context.getLeaf(); - java.util.Optional<ScmInfo> scmInfo = scmInfoRepository.getScmInfo(leaf); - if (!scmInfo.isPresent() || !context.hasPeriod()) { + java.util.Optional<Set<Integer>> changedLines = newLinesRepository.getNewLines(leaf); + if (!changedLines.isPresent()) { return; } @@ -118,21 +111,18 @@ public class NewSizeMeasuresStep implements ComputationStep { if (leaf.getType() != Component.Type.FILE) { newDuplicatedLines.increment(0); newDuplicatedBlocks.increment(0); - return; + } else { + initNewLines(changedLines.get()); + initNewDuplicated(leaf, changedLines.get()); } - - initNewLines(scmInfo.get(), context.getPeriod()); - initNewDuplicated(leaf, scmInfo.get(), context.getPeriod()); } - private void initNewLines(ScmInfo scmInfo, Period period) { - scmInfo.getAllChangesets().values().stream() - .filter(changeset -> isLineInPeriod(changeset, period)) - .forEach(changeset -> newLines.increment(1)); + private void initNewLines(Set<Integer> changedLines) { + newLines.increment(changedLines.size()); } - private void initNewDuplicated(Component component, ScmInfo scmInfo, Period period) { - DuplicationCounters duplicationCounters = new DuplicationCounters(scmInfo, period, scmInfo.getAllChangesets().size()); + private void initNewDuplicated(Component component, Set<Integer> changedLines) { + DuplicationCounters duplicationCounters = new DuplicationCounters(changedLines); Iterable<Duplication> duplications = duplicationRepository.getDuplications(component); for (Duplication duplication : duplications) { duplicationCounters.addBlock(duplication.getOriginal()); @@ -145,29 +135,22 @@ public class NewSizeMeasuresStep implements ComputationStep { newDuplicatedLines.increment(duplicationCounters.getNewLinesDuplicated()); newDuplicatedBlocks.increment(duplicationCounters.getNewBlocksDuplicated()); } - - private static boolean isLineInPeriod(Changeset changeset, Period period) { - return changeset.getDate() > period.getSnapshotDate(); - } } private static class DuplicationCounters { - private final ScmInfo scmInfo; - private final Period period; + private final Set<Integer> changedLines; private final Set<Integer> lineCounts; private int blockCounts; - private DuplicationCounters(ScmInfo scmInfo, Period period, int changesetSize) { - this.scmInfo = scmInfo; - this.period = period; - this.lineCounts = new HashSet<>(changesetSize); + private DuplicationCounters(Set<Integer> changedLines) { + this.changedLines = changedLines; + this.lineCounts = new HashSet<>(changedLines.size()); } void addBlock(TextBlock textBlock) { Boolean[] newBlock = new Boolean[] {false}; IntStream.rangeClosed(textBlock.getStart(), textBlock.getEnd()) - .filter(scmInfo::hasChangesetForLine) - .filter(line -> isLineInPeriod(line, period)) + .filter(changedLines::contains) .forEach(line -> { lineCounts.add(line); newBlock[0] = true; @@ -184,25 +167,20 @@ public class NewSizeMeasuresStep implements ComputationStep { int getNewBlocksDuplicated() { return blockCounts; } - - private boolean isLineInPeriod(int lineNumber, Period period) { - return scmInfo.getChangesetForLine(lineNumber).getDate() > period.getSnapshotDate(); - } } private static final class NewDuplicationFormula implements Formula<NewSizeCounter> { private final DuplicationRepository duplicationRepository; - private final ScmInfoRepository scmInfoRepository; + private final NewLinesRepository newLinesRepository; - private NewDuplicationFormula(ScmInfoRepository scmInfoRepository, - DuplicationRepository duplicationRepository) { + private NewDuplicationFormula(NewLinesRepository newLinesRepository, DuplicationRepository duplicationRepository) { this.duplicationRepository = duplicationRepository; - this.scmInfoRepository = scmInfoRepository; + this.newLinesRepository = newLinesRepository; } @Override public NewSizeCounter createNewCounter() { - return new NewSizeCounter(duplicationRepository, scmInfoRepository); + return new NewSizeCounter(duplicationRepository, newLinesRepository); } @Override diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/AverageFormulaTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/AverageFormulaTest.java index 96e93cc96d9..9a355b83701 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/AverageFormulaTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/AverageFormulaTest.java @@ -28,7 +28,6 @@ import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.ReportComponent; import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.ce.task.projectanalysis.period.PeriodHolder; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; @@ -49,7 +48,7 @@ public class AverageFormulaTest { CounterInitializationContext counterInitializationContext = mock(CounterInitializationContext.class); CreateMeasureContext createMeasureContext = new DumbCreateMeasureContext( - ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class), mock(PeriodHolder.class)); + ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class)); @Rule public ExpectedException thrown = ExpectedException.none(); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/DistributionFormulaTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/DistributionFormulaTest.java index 7515afe2d65..58637b42e18 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/DistributionFormulaTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/DistributionFormulaTest.java @@ -28,7 +28,6 @@ import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.ReportComponent; import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.ce.task.projectanalysis.period.PeriodHolder; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -44,9 +43,9 @@ public class DistributionFormulaTest { CounterInitializationContext counterInitializationContext = mock(CounterInitializationContext.class); CreateMeasureContext projectCreateMeasureContext = new DumbCreateMeasureContext( - ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class), mock(PeriodHolder.class)); + ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class)); CreateMeasureContext fileCreateMeasureContext = new DumbCreateMeasureContext( - ReportComponent.builder(Component.Type.FILE, 1).build(), mock(Metric.class), mock(PeriodHolder.class)); + ReportComponent.builder(Component.Type.FILE, 1).build(), mock(Metric.class)); @Test public void check_new_counter_class() { diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/DumbCreateMeasureContext.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/DumbCreateMeasureContext.java index c9e89b12603..a34bc9973a7 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/DumbCreateMeasureContext.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/DumbCreateMeasureContext.java @@ -21,18 +21,14 @@ package org.sonar.ce.task.projectanalysis.formula; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolder; public class DumbCreateMeasureContext implements CreateMeasureContext { private final Component component; private final Metric metric; - private final PeriodHolder periodHolder; - public DumbCreateMeasureContext(Component component, Metric metric, PeriodHolder periodHolder) { + public DumbCreateMeasureContext(Component component, Metric metric) { this.component = component; this.metric = metric; - this.periodHolder = periodHolder; } @Override @@ -45,13 +41,4 @@ public class DumbCreateMeasureContext implements CreateMeasureContext { return metric; } - @Override - public Period getPeriod() { - return periodHolder.getPeriod(); - } - - @Override - public boolean hasPeriod() { - return periodHolder.hasPeriod(); - } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/IntSumFormulaTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/IntSumFormulaTest.java index 1bdf830b58a..3338ae9f1ce 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/IntSumFormulaTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/IntSumFormulaTest.java @@ -31,7 +31,6 @@ import org.sonar.ce.task.projectanalysis.formula.SumFormula.IntSumFormula; import org.sonar.ce.task.projectanalysis.formula.counter.IntSumCounter; import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.ce.task.projectanalysis.period.PeriodHolder; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -49,9 +48,9 @@ public class IntSumFormulaTest { public ExpectedException thrown = ExpectedException.none(); CreateMeasureContext projectCreateMeasureContext = new DumbCreateMeasureContext( - ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class), mock(PeriodHolder.class)); + ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class)); CreateMeasureContext fileCreateMeasureContext = new DumbCreateMeasureContext( - ReportComponent.builder(Component.Type.FILE, 2).build(), mock(Metric.class), mock(PeriodHolder.class)); + ReportComponent.builder(Component.Type.FILE, 2).build(), mock(Metric.class)); @Test public void check_create_new_counter_class() { diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/LongSumFormulaTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/LongSumFormulaTest.java index b2945f8f6d1..3bb9101060d 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/LongSumFormulaTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/LongSumFormulaTest.java @@ -30,7 +30,6 @@ import org.sonar.ce.task.projectanalysis.component.ReportComponent; import org.sonar.ce.task.projectanalysis.formula.counter.LongSumCounter; import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.ce.task.projectanalysis.period.PeriodHolder; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -48,9 +47,9 @@ public class LongSumFormulaTest { public ExpectedException thrown = ExpectedException.none(); CreateMeasureContext projectCreateMeasureContext = new DumbCreateMeasureContext( - ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class), mock(PeriodHolder.class)); + ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class)); CreateMeasureContext fileCreateMeasureContext = new DumbCreateMeasureContext( - ReportComponent.builder(Component.Type.FILE, 2).build(), mock(Metric.class), mock(PeriodHolder.class)); + ReportComponent.builder(Component.Type.FILE, 2).build(), mock(Metric.class)); @Test public void check_create_new_counter_class() { diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ReportFormulaExecutorComponentVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ReportFormulaExecutorComponentVisitorTest.java index fca007a2c9c..7d4944a18ab 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ReportFormulaExecutorComponentVisitorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ReportFormulaExecutorComponentVisitorTest.java @@ -34,8 +34,6 @@ import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule; import org.sonar.ce.task.projectanalysis.metric.Metric; import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.measures.CoreMetrics.LINES_KEY; @@ -92,8 +90,6 @@ public class ReportFormulaExecutorComponentVisitorTest { .add(CoreMetrics.NEW_COVERAGE); @Rule public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - @Rule - public PeriodHolderRule periodsHolder = new PeriodHolderRule().setPeriod(new Period("some mode", null, 95l, "756l")); @Test public void verify_aggregation_on_value() { @@ -294,7 +290,6 @@ public class ReportFormulaExecutorComponentVisitorTest { private FormulaExecutorComponentVisitor formulaExecutorComponentVisitor(Formula formula) { return FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository) - .withVariationSupport(periodsHolder) .buildFor(ImmutableList.of(formula)); } @@ -321,7 +316,6 @@ public class ReportFormulaExecutorComponentVisitorTest { @Override public Optional<Measure> createMeasure(FakeCounter counter, CreateMeasureContext context) { // verify the context which is passed to the method - assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod()); assertThat(context.getComponent()).isNotNull(); assertThat(context.getMetric()).isSameAs(metricRepository.getByKey(NCLOC_KEY)); @@ -344,7 +338,6 @@ public class ReportFormulaExecutorComponentVisitorTest { @Override public Optional<Measure> createMeasure(FakeCounter counter, CreateMeasureContext context) { // verify the context which is passed to the method - assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod()); assertThat(context.getComponent()).isNotNull(); assertThat(context.getMetric()) .isIn(metricRepository.getByKey(NEW_LINES_TO_COVER_KEY), metricRepository.getByKey(NEW_COVERAGE_KEY)); @@ -380,7 +373,6 @@ public class ReportFormulaExecutorComponentVisitorTest { public void initialize(CounterInitializationContext context) { // verify the context which is passed to the method assertThat(context.getLeaf().getChildren()).isEmpty(); - assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod()); Optional<Measure> measureOptional = context.getMeasure(LINES_KEY); if (measureOptional.isPresent()) { @@ -399,7 +391,6 @@ public class ReportFormulaExecutorComponentVisitorTest { @Override public Optional<Measure> createMeasure(FakeVariationCounter counter, CreateMeasureContext context) { // verify the context which is passed to the method - assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod()); assertThat(context.getComponent()).isNotNull(); assertThat(context.getMetric()).isSameAs(metricRepository.getByKey(NEW_COVERAGE_KEY)); @@ -431,10 +422,9 @@ public class ReportFormulaExecutorComponentVisitorTest { public void initialize(CounterInitializationContext context) { // verify the context which is passed to the method assertThat(context.getLeaf().getChildren()).isEmpty(); - assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod()); Optional<Measure> measureOptional = context.getMeasure(NEW_LINES_TO_COVER_KEY); - if (!measureOptional.isPresent() || !context.hasPeriod()) { + if (!measureOptional.isPresent()) { return; } this.values.increment((int) measureOptional.get().getVariation()); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ViewsFormulaExecutorComponentVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ViewsFormulaExecutorComponentVisitorTest.java index 266c68877e6..2dac82ceef7 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ViewsFormulaExecutorComponentVisitorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ViewsFormulaExecutorComponentVisitorTest.java @@ -32,8 +32,6 @@ import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule; import org.sonar.ce.task.projectanalysis.metric.Metric; import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.guava.api.Assertions.assertThat; @@ -86,8 +84,6 @@ public class ViewsFormulaExecutorComponentVisitorTest { .add(CoreMetrics.NEW_COVERAGE); @Rule public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - @Rule - public PeriodHolderRule periodsHolder = new PeriodHolderRule().setPeriod(new Period("some mode", null, 95l, "u1")); @Test public void verify_aggregation_on_value() { @@ -213,7 +209,6 @@ public class ViewsFormulaExecutorComponentVisitorTest { @Override public Optional<Measure> createMeasure(FakeCounter counter, CreateMeasureContext context) { // verify the context which is passed to the method - assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod()); assertThat(context.getComponent()).isNotNull(); assertThat(context.getMetric()).isSameAs(metricRepository.getByKey(NCLOC_KEY)); @@ -236,7 +231,6 @@ public class ViewsFormulaExecutorComponentVisitorTest { @Override public Optional<Measure> createMeasure(FakeCounter counter, CreateMeasureContext context) { // verify the context which is passed to the method - assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod()); assertThat(context.getComponent()).isNotNull(); assertThat(context.getMetric()) .isIn(metricRepository.getByKey(NEW_LINES_TO_COVER_KEY), metricRepository.getByKey(NEW_COVERAGE_KEY)); @@ -289,7 +283,6 @@ public class ViewsFormulaExecutorComponentVisitorTest { @Override public Optional<Measure> createMeasure(FakeVariationCounter counter, CreateMeasureContext context) { // verify the context which is passed to the method - assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod()); assertThat(context.getComponent()).isNotNull(); assertThat(context.getMetric()).isSameAs(metricRepository.getByKey(NEW_COVERAGE_KEY)); @@ -322,7 +315,7 @@ public class ViewsFormulaExecutorComponentVisitorTest { verifyLeafContext(context); Optional<Measure> measureOptional = context.getMeasure(NEW_LINES_TO_COVER_KEY); - if (!measureOptional.isPresent() || !context.hasPeriod()) { + if (!measureOptional.isPresent()) { return; } this.values.increment((int) measureOptional.get().getVariation()); @@ -332,7 +325,6 @@ public class ViewsFormulaExecutorComponentVisitorTest { private FormulaExecutorComponentVisitor formulaExecutorComponentVisitor(Formula formula) { return FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository) - .withVariationSupport(periodsHolder) .buildFor(ImmutableList.of(formula)); } @@ -361,7 +353,6 @@ public class ViewsFormulaExecutorComponentVisitorTest { private void verifyLeafContext(CounterInitializationContext context) { assertThat(context.getLeaf().getChildren()).isEmpty(); - assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod()); } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/coverage/CoverageUtilsTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/coverage/CoverageUtilsTest.java index 10e22c55cdd..b0933675b2f 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/coverage/CoverageUtilsTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/coverage/CoverageUtilsTest.java @@ -29,7 +29,6 @@ import org.junit.rules.ExternalResource; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.formula.CounterInitializationContext; import org.sonar.ce.task.projectanalysis.measure.Measure; -import org.sonar.ce.task.projectanalysis.period.Period; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; @@ -134,14 +133,5 @@ public class CoverageUtilsTest { return Optional.fromNullable(measures.get(metricKey)); } - @Override - public Period getPeriod() { - throw new UnsupportedOperationException("getPeriod is not supported"); - } - - @Override - public boolean hasPeriod() { - throw new UnsupportedOperationException("hasPeriod is not supported"); - } } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java index 2d126d090cd..4acca918552 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java @@ -23,9 +23,9 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Ordering; import java.util.Arrays; -import java.util.Map; +import java.util.HashSet; +import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; import org.assertj.core.data.Offset; import org.junit.Before; import org.junit.Rule; @@ -39,10 +39,7 @@ import org.sonar.ce.task.projectanalysis.component.VisitorsCrawler; import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule; import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule; -import org.sonar.ce.task.projectanalysis.scm.Changeset; -import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryRule; +import org.sonar.ce.task.projectanalysis.source.NewLinesRepository; import org.sonar.server.measure.DebtRatingGrid; import org.sonar.server.measure.Rating; @@ -74,16 +71,11 @@ public class NewMaintainabilityMeasuresVisitorTest { private static final String LANGUAGE_1_KEY = "language 1 key"; private static final long LANGUAGE_1_DEV_COST = 30l; - private static final long PERIOD_SNAPSHOT_DATE = 12323l; - private static final String SOME_ANALYSIS_UUID = "9993l"; - private static final String SOME_PERIOD_MODE = "some mode"; private static final int ROOT_REF = 1; private static final int LANGUAGE_1_FILE_REF = 11111; private static final Offset<Double> VARIATION_COMPARISON_OFFSET = Offset.offset(0.01); @Rule - public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule(); - @Rule public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); @Rule public MetricRepositoryRule metricRepository = new MetricRepositoryRule() @@ -94,9 +86,8 @@ public class NewMaintainabilityMeasuresVisitorTest { .add(NEW_DEVELOPMENT_COST); @Rule public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - @Rule - public PeriodHolderRule periodsHolder = new PeriodHolderRule(); + private NewLinesRepository newLinesRepository = mock(NewLinesRepository.class); private RatingSettings ratingSettings = mock(RatingSettings.class); private VisitorsCrawler underTest; @@ -104,13 +95,12 @@ public class NewMaintainabilityMeasuresVisitorTest { @Before public void setUp() throws Exception { when(ratingSettings.getDebtRatingGrid()).thenReturn(new DebtRatingGrid(RATING_GRID)); - underTest = new VisitorsCrawler(Arrays.asList(new NewMaintainabilityMeasuresVisitor(metricRepository, measureRepository, scmInfoRepository, - periodsHolder, ratingSettings))); + underTest = new VisitorsCrawler(Arrays.asList(new NewMaintainabilityMeasuresVisitor(metricRepository, measureRepository, newLinesRepository, ratingSettings))); } @Test - public void project_has_new_measures_for_each_defined_period() { - setPeriod(); + public void project_has_new_measures() { + when(newLinesRepository.newLinesAvailable()).thenReturn(true); treeRootHolder.setRoot(builder(PROJECT, ROOT_REF).build()); underTest.visit(treeRootHolder.getRoot()); @@ -120,8 +110,8 @@ public class NewMaintainabilityMeasuresVisitorTest { } @Test - public void project_has_no_measure_if_there_is_no_period() { - periodsHolder.setPeriod(null); + public void project_has_no_measure_if_new_lines_not_available() { + when(newLinesRepository.newLinesAvailable()).thenReturn(false); treeRootHolder.setRoot(builder(PROJECT, ROOT_REF).build()); underTest.visit(treeRootHolder.getRoot()); @@ -131,10 +121,10 @@ public class NewMaintainabilityMeasuresVisitorTest { } @Test - public void file_has_no_new_debt_ratio_variation_if_there_is_no_period() { - periodsHolder.setPeriod(null); + public void file_has_no_new_debt_ratio_variation_if_new_lines_not_available() { + when(newLinesRepository.newLinesAvailable()).thenReturn(false); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET); + setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50)); underTest.visit(treeRootHolder.getRoot()); @@ -144,16 +134,15 @@ public class NewMaintainabilityMeasuresVisitorTest { } @Test - public void file_has_0_new_debt_ratio_if_all_scm_dates_are_before_snapshot_dates() { - setPeriod(); + public void file_has_0_new_debt_ratio_if_no_line_is_new() { + ReportComponent file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build(); treeRootHolder.setRoot( builder(PROJECT, ROOT_REF) - .addChildren( - builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build()) + .addChildren(file) .build()); measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50)); measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4)); - scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 4)); + setNewLines(file); underTest.visit(treeRootHolder.getRoot()); @@ -162,23 +151,10 @@ public class NewMaintainabilityMeasuresVisitorTest { } @Test - public void file_has_new_debt_ratio_if_some_scm_dates_are_after_snapshot_dates() { - setPeriod(); - when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET); - measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50)); - - underTest.visit(treeRootHolder.getRoot()); - - assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 83.33); - assertNewDebtRatioValues(ROOT_REF, 83.33); - } - - @Test - public void file_has_new_debt_ratio_if_only_has_some_scm_dates_which_are_after_snapshot_dates() { - setPeriod(); + public void file_has_new_debt_ratio_if_some_lines_are_new() { + when(newLinesRepository.newLinesAvailable()).thenReturn(true); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProjectWithPartialChangesets(50, Flag.SRC_FILE, Flag.WITH_NCLOC); + setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50)); underTest.visit(treeRootHolder.getRoot()); @@ -189,9 +165,8 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void new_debt_ratio_changes_with_language_cost() { - setPeriod(); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST * 10); - setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET); + setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50)); underTest.visit(treeRootHolder.getRoot()); @@ -202,9 +177,8 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void new_debt_ratio_changes_with_new_technical_debt() { - setPeriod(); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProject(500, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET); + setupOneFileAloneInAProject(500, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(500)); underTest.visit(treeRootHolder.getRoot()); @@ -215,9 +189,8 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void new_debt_ratio_on_non_file_level_is_based_on_new_technical_debt_of_that_level() { - setPeriod(); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProject(500, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET); + setupOneFileAloneInAProject(500, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(1200)); underTest.visit(treeRootHolder.getRoot()); @@ -228,9 +201,8 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void new_debt_ratio_when_file_is_unit_test() { - setPeriod(); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProject(500, Flag.UT_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET); + setupOneFileAloneInAProject(500, Flag.UT_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(1200)); underTest.visit(treeRootHolder.getRoot()); @@ -240,10 +212,10 @@ public class NewMaintainabilityMeasuresVisitorTest { } @Test - public void new_debt_ratio_is_0_when_file_has_no_changesets() { - setPeriod(); + public void new_debt_ratio_is_0_when_file_has_no_new_lines() { + when(newLinesRepository.newLinesAvailable()).thenReturn(true); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_CHANGESET); + setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50)); underTest.visit(treeRootHolder.getRoot()); @@ -253,10 +225,10 @@ public class NewMaintainabilityMeasuresVisitorTest { } @Test - public void new_debt_ratio_is_0_on_non_file_level_when_no_file_has_changesets() { - setPeriod(); + public void new_debt_ratio_is_0_on_non_file_level_when_no_file_has_new_lines() { + when(newLinesRepository.newLinesAvailable()).thenReturn(true); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_CHANGESET); + setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(200)); underTest.visit(treeRootHolder.getRoot()); @@ -267,9 +239,8 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void new_debt_ratio_is_0_when_there_is_no_ncloc_in_file() { - setPeriod(); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_CHANGESET); + setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50)); underTest.visit(treeRootHolder.getRoot()); @@ -280,9 +251,8 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void new_debt_ratio_is_0_on_non_file_level_when_one_file_has_zero_new_debt_because_of_no_changeset() { - setPeriod(); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_CHANGESET); + setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(200)); underTest.visit(treeRootHolder.getRoot()); @@ -293,9 +263,8 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void new_debt_ratio_is_0_when_ncloc_measure_is_missing() { - setPeriod(); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); - setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.MISSING_MEASURE_NCLOC, Flag.WITH_CHANGESET); + setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.MISSING_MEASURE_NCLOC, Flag.WITH_NEW_LINES); measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50)); underTest.visit(treeRootHolder.getRoot()); @@ -306,16 +275,15 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void leaf_components_always_have_a_measure_when_at_least_one_period_exist_and_ratio_is_computed_from_current_level_new_debt() { - setPeriod(); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); + Component file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build(); treeRootHolder.setRoot( builder(PROJECT, ROOT_REF) .addChildren( builder(MODULE, 11) .addChildren( builder(DIRECTORY, 111) - .addChildren( - builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build()) + .addChildren(file) .build()) .build()) .build()); @@ -328,8 +296,7 @@ public class NewMaintainabilityMeasuresVisitorTest { // 4 lines file, only first one is not ncloc measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4)); // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date - scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 2, PERIOD_SNAPSHOT_DATE + 100, 2)); - + setNewLines(file, 3, 4); underTest.visit(treeRootHolder.getRoot()); assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 83.33); @@ -340,16 +307,15 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void compute_new_maintainability_rating() { - setPeriod(); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); + ReportComponent file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build(); treeRootHolder.setRoot( builder(PROJECT, ROOT_REF) .addChildren( builder(MODULE, 11) .addChildren( builder(DIRECTORY, 111) - .addChildren( - builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build()) + .addChildren(file) .build()) .build()) .build()); @@ -362,7 +328,8 @@ public class NewMaintainabilityMeasuresVisitorTest { // 4 lines file, only first one is not ncloc measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4)); // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date - scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 2, PERIOD_SNAPSHOT_DATE + 100, 2)); + + setNewLines(file, 3, 4); underTest.visit(treeRootHolder.getRoot()); @@ -374,7 +341,8 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void compute_new_development_cost() { - setPeriod(); + ReportComponent file1 = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 4)).build(); + ReportComponent file2 = builder(FILE, 22_222).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 6)).build(); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); treeRootHolder.setRoot( builder(PROJECT, ROOT_REF) @@ -382,9 +350,7 @@ public class NewMaintainabilityMeasuresVisitorTest { builder(MODULE, 11) .addChildren( builder(DIRECTORY, 111) - .addChildren( - builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 4)).build(), - builder(FILE, 22_222).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 6)).build()) + .addChildren(file1, file2) .build()) .build()) .build()); @@ -392,11 +358,12 @@ public class NewMaintainabilityMeasuresVisitorTest { // 4 lines file, only first one is not ncloc measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4)); // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date - scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 2, PERIOD_SNAPSHOT_DATE + 100, 2)); + setNewLines(file1, 3, 4); + // 6 lines file, only last one is not ncloc measureRepository.addRawMeasure(22_222, NCLOC_DATA_KEY, createNclocDataMeasure(1, 2, 3, 4, 5)); // first 2 lines are before all snapshots, 4 last lines are after PERIOD 2's snapshot date - scmInfoRepository.setScmInfo(22_222, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 2, PERIOD_SNAPSHOT_DATE + 100, 4)); + setNewLines(file2, 3, 4, 5, 6); underTest.visit(treeRootHolder.getRoot()); @@ -407,7 +374,7 @@ public class NewMaintainabilityMeasuresVisitorTest { @Test public void compute_new_maintainability_rating_to_A_when_no_debt() { - setPeriod(); + when(newLinesRepository.newLinesAvailable()).thenReturn(true); when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); treeRootHolder.setRoot( builder(PROJECT, ROOT_REF) @@ -429,15 +396,15 @@ public class NewMaintainabilityMeasuresVisitorTest { assertNewMaintainability(ROOT_REF, A); } - private void setupOneFileAloneInAProject(int newDebt, Flag isUnitTest, Flag withNclocLines, Flag withChangeSets) { + private void setupOneFileAloneInAProject(int newDebt, Flag isUnitTest, Flag withNclocLines, Flag withNewLines) { checkArgument(isUnitTest == Flag.UT_FILE || isUnitTest == Flag.SRC_FILE); checkArgument(withNclocLines == Flag.WITH_NCLOC || withNclocLines == Flag.NO_NCLOC || withNclocLines == Flag.MISSING_MEASURE_NCLOC); - checkArgument(withChangeSets == Flag.WITH_CHANGESET || withChangeSets == Flag.NO_CHANGESET); + checkArgument(withNewLines == Flag.WITH_NEW_LINES || withNewLines == Flag.NO_NEW_LINES); + Component file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(isUnitTest == Flag.UT_FILE, LANGUAGE_1_KEY, 1)).build(); treeRootHolder.setRoot( builder(PROJECT, ROOT_REF) - .addChildren( - builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(isUnitTest == Flag.UT_FILE, LANGUAGE_1_KEY, 1)).build()) + .addChildren(file) .build()); Measure newDebtMeasure = createNewDebtMeasure(newDebt); @@ -449,37 +416,24 @@ public class NewMaintainabilityMeasuresVisitorTest { // 4 lines file, none of which is ncloc measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNoNclocDataMeasure(4)); } - if (withChangeSets == Flag.WITH_CHANGESET) { - // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date - scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 2, PERIOD_SNAPSHOT_DATE + 100, 2)); + if (withNewLines == Flag.WITH_NEW_LINES) { + // 2 last lines are new + setNewLines(file, 3, 4); } } - private void setupOneFileAloneInAProjectWithPartialChangesets(int newDebt, Flag isUnitTest, Flag withNclocLines) { - checkArgument(isUnitTest == Flag.UT_FILE || isUnitTest == Flag.SRC_FILE); - checkArgument(withNclocLines == Flag.WITH_NCLOC || withNclocLines == Flag.NO_NCLOC || withNclocLines == Flag.MISSING_MEASURE_NCLOC); - - treeRootHolder.setRoot( - builder(PROJECT, ROOT_REF) - .addChildren( - builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(isUnitTest == Flag.UT_FILE, LANGUAGE_1_KEY, 1)).build()) - .build()); - - Measure newDebtMeasure = createNewDebtMeasure(newDebt); - measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NEW_TECHNICAL_DEBT_KEY, newDebtMeasure); - if (withNclocLines == Flag.WITH_NCLOC) { - // 4 lines file, only first one is not ncloc - measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4)); - } else if (withNclocLines == Flag.NO_NCLOC) { - // 4 lines file, none of which is ncloc - measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNoNclocDataMeasure(4)); + private void setNewLines(Component component, int... lineNumbers) { + HashSet<Integer> newLines = new HashSet<>(); + for (int i : lineNumbers) { + newLines.add(i); } - // 2 last lines are after PERIOD 2's snapshot date - scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesetsForLines(PERIOD_SNAPSHOT_DATE + 100, 3, 4)); + when(newLinesRepository.newLinesAvailable()).thenReturn(true); + when(newLinesRepository.getNewLines(component)).thenReturn(Optional.of(newLines)); + } private enum Flag { - UT_FILE, SRC_FILE, NO_CHANGESET, WITH_CHANGESET, WITH_NCLOC, NO_NCLOC, MISSING_MEASURE_NCLOC + UT_FILE, SRC_FILE, NO_NEW_LINES, WITH_NEW_LINES, WITH_NCLOC, NO_NCLOC, MISSING_MEASURE_NCLOC } public static ReportComponent.Builder builder(Component.Type type, int ref) { @@ -508,43 +462,6 @@ public class NewMaintainabilityMeasuresVisitorTest { return newMeasureBuilder().create(KeyValueFormat.format(builder.build(), KeyValueFormat.newIntegerConverter(), KeyValueFormat.newIntegerConverter())); } - /** - * Creates changesets of {@code lines} lines which all have the same date {@code scmDate}. - */ - private static Changeset[] createChangesets(long scmDate, int lines) { - Changeset changetset = Changeset.newChangesetBuilder().setDate(scmDate).setRevision("rev-1").build(); - Changeset[] changesets = new Changeset[lines]; - for (int i = 0; i < lines; i++) { - changesets[i] = changetset; - } - return changesets; - } - - /** - * Creates changesets for specific lines, which all have the same date {@code scmDate}. - */ - private static Map<Integer, Changeset> createChangesetsForLines(long scmDate, int... lines) { - Changeset changetset = Changeset.newChangesetBuilder().setDate(scmDate).setRevision("rev-1").build(); - return Arrays.stream(lines).boxed().collect(Collectors.toMap(l -> l, l -> changetset)); - } - - /** - * Creates a changeset of {@code lineCount} lines which have the date {@code scmDate} and {@code otherLineCount} lines which - * have the date {@code otherScmDate}. - */ - private static Changeset[] createChangesets(long scmDate, int lineCount, long otherScmDate, int otherLineCount) { - Changeset[] changesets = new Changeset[lineCount + otherLineCount]; - Changeset changetset1 = Changeset.newChangesetBuilder().setDate(scmDate).setRevision("rev-1").build(); - for (int i = 0; i < lineCount; i++) { - changesets[i] = changetset1; - } - Changeset changetset2 = Changeset.newChangesetBuilder().setDate(otherScmDate).setRevision("rev-2").build(); - for (int i = lineCount; i < lineCount + otherLineCount; i++) { - changesets[i] = changetset2; - } - return changesets; - } - private void assertNoNewDebtRatioMeasure(int componentRef) { assertThat(measureRepository.getAddedRawMeasure(componentRef, NEW_SQALE_DEBT_RATIO_KEY)) .isAbsent(); @@ -566,8 +483,4 @@ public class NewMaintainabilityMeasuresVisitorTest { assertThat(measureRepository.getAddedRawMeasure(componentRef, NEW_MAINTAINABILITY_RATING_KEY)) .isAbsent(); } - - private void setPeriod() { - periodsHolder.setPeriod(new Period(SOME_PERIOD_MODE, null, PERIOD_SNAPSHOT_DATE, SOME_ANALYSIS_UUID)); - } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepositoryTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepositoryTest.java new file mode 100644 index 00000000000..2a02b3473a0 --- /dev/null +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepositoryTest.java @@ -0,0 +1,124 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.ce.task.projectanalysis.source; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; +import org.sonar.ce.task.projectanalysis.analysis.Branch; +import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule; +import org.sonar.ce.task.projectanalysis.component.Component; +import org.sonar.ce.task.projectanalysis.component.ReportComponent; +import org.sonar.ce.task.projectanalysis.period.Period; +import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule; +import org.sonar.ce.task.projectanalysis.scm.Changeset; +import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryRule; +import org.sonar.db.component.BranchType; +import org.sonar.scanner.protocol.output.ScannerReport; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class NewLinesRepositoryTest { + private final static ReportComponent FILE = ReportComponent.builder(Component.Type.FILE, 1).build(); + + @Rule + public BatchReportReaderRule reader = new BatchReportReaderRule(); + @Rule + public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule(); + @Rule + public PeriodHolderRule periodHolder = new PeriodHolderRule(); + @Rule + public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule(); + + private NewLinesRepository repository = new NewLinesRepository(reader, analysisMetadataHolder, periodHolder, scmInfoRepository); + + @Test + public void load_new_lines_from_report_if_available_and_pullrequest() { + periodHolder.setPeriod(new Period("", null, Long.MAX_VALUE, "")); + setPullRequest(); + createChangedLinesInReport(1, 2, 5); + + Optional<Set<Integer>> newLines = repository.getNewLines(FILE); + + assertThat(newLines).isPresent(); + assertThat(newLines.get()).containsOnly(1, 2, 5); + assertThat(repository.newLinesAvailable()).isTrue(); + } + + @Test + public void calculate_new_lines_from_period() { + periodHolder.setPeriod(new Period("", null, 1000L, "")); + scmInfoRepository.setScmInfo(FILE.getReportAttributes().getRef(), createChangesets(1100L, 900L, 1000L, 800L)); + + Optional<Set<Integer>> newLines = repository.getNewLines(FILE); + + assertThat(newLines).isPresent(); + assertThat(newLines.get()).containsOnly(1); + assertThat(repository.newLinesAvailable()).isTrue(); + } + + @Test + public void return_empty_if_no_period() { + periodHolder.setPeriod(null); + + // even though we have lines in the report and scm data, nothing should be returned since we have no period + createChangedLinesInReport(1, 2, 5); + scmInfoRepository.setScmInfo(FILE.getReportAttributes().getRef(), createChangesets(1100L, 900L, 1000L, 800L)); + + Optional<Set<Integer>> newLines = repository.getNewLines(FILE); + + assertThat(newLines).isNotPresent(); + assertThat(repository.newLinesAvailable()).isFalse(); + } + + @Test + public void return_empty_if_no_report_and_no_scm_info() { + periodHolder.setPeriod(new Period("", null, 1000L, "")); + + Optional<Set<Integer>> newLines = repository.getNewLines(FILE); + + assertThat(newLines).isNotPresent(); + assertThat(repository.newLinesAvailable()).isTrue(); + } + + private void setPullRequest() { + Branch branch = mock(Branch.class); + when(branch.getType()).thenReturn(BranchType.PULL_REQUEST); + analysisMetadataHolder.setBranch(branch); + } + + private Changeset[] createChangesets(Long... dates) { + return Arrays.stream(dates) + .map(l -> Changeset.newChangesetBuilder().setDate(l).build()) + .toArray(Changeset[]::new); + } + + private void createChangedLinesInReport(Integer... lines) { + ScannerReport.ChangedLines changedLines = ScannerReport.ChangedLines.newBuilder() + .addAllLine(Arrays.asList(lines)) + .build(); + reader.putChangedLines(FILE.getReportAttributes().getRef(), changedLines); + } +} diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/NewSizeMeasuresStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/NewSizeMeasuresStepTest.java index 2b983b6c1a4..2bbd57d3c8f 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/NewSizeMeasuresStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/NewSizeMeasuresStepTest.java @@ -20,23 +20,26 @@ package org.sonar.ce.task.projectanalysis.step; import java.util.Arrays; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; import org.assertj.core.data.Offset; import org.junit.Rule; import org.junit.Test; +import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; import org.sonar.ce.task.projectanalysis.duplication.DuplicationRepositoryRule; import org.sonar.ce.task.projectanalysis.duplication.TextBlock; import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule; import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule; -import org.sonar.ce.task.projectanalysis.scm.Changeset; -import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryRule; +import org.sonar.ce.task.projectanalysis.source.NewLinesRepository; import org.sonar.ce.task.step.TestComputationStepContext; import static com.google.common.base.Preconditions.checkArgument; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.guava.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static org.sonar.api.measures.CoreMetrics.NEW_BLOCKS_DUPLICATED; import static org.sonar.api.measures.CoreMetrics.NEW_BLOCKS_DUPLICATED_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES; @@ -45,7 +48,6 @@ import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_KE import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_LINES; import static org.sonar.api.measures.CoreMetrics.NEW_LINES_KEY; -import static org.sonar.api.utils.DateUtils.parseDate; import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY; import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE; import static org.sonar.ce.task.projectanalysis.component.Component.Type.MODULE; @@ -66,6 +68,11 @@ public class NewSizeMeasuresStepTest { private static final int FILE_2_REF = 12342; private static final int FILE_3_REF = 1261; private static final int FILE_4_REF = 1262; + private static final Component FILE_1 = builder(FILE, FILE_1_REF).build(); + private static final Component FILE_2 = builder(FILE, FILE_2_REF).build(); + private static final Component FILE_3 = builder(FILE, FILE_3_REF).build(); + private static final Component FILE_4 = builder(FILE, FILE_4_REF).build(); + private static final String SOME_FILE_KEY = "some file key"; @Rule @@ -78,28 +85,17 @@ public class NewSizeMeasuresStepTest { builder(MODULE, SUB_MODULE_1_REF) .addChildren( builder(DIRECTORY, DIRECTORY_REF) - .addChildren( - builder(FILE, FILE_1_REF).build(), - builder(FILE, FILE_2_REF).build()) + .addChildren(FILE_1, FILE_2) .build(), builder(DIRECTORY, DIRECTORY_2_REF).build()) .build(), builder(MODULE, SUB_MODULE_2_REF) - .addChildren( - builder(FILE, FILE_3_REF).build(), - builder(FILE, FILE_4_REF).build()) + .addChildren(FILE_3, FILE_4) .build()) .build()) .build()); @Rule - public PeriodHolderRule periodsHolder = new PeriodHolderRule().setPeriod( - new Period("mode_p_1", null, parseDate("2009-12-25").getTime(), "u1")); - - @Rule - public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule(); - - @Rule public MetricRepositoryRule metricRepository = new MetricRepositoryRule() .add(NEW_LINES) .add(NEW_DUPLICATED_LINES) @@ -111,14 +107,13 @@ public class NewSizeMeasuresStepTest { @Rule public DuplicationRepositoryRule duplicationRepository = DuplicationRepositoryRule.create(treeRootHolder); + private NewLinesRepository newLinesRepository = mock(NewLinesRepository.class); - private NewSizeMeasuresStep underTest = new NewSizeMeasuresStep(treeRootHolder, periodsHolder, metricRepository, measureRepository, scmInfoRepository, - duplicationRepository); + private NewSizeMeasuresStep underTest = new NewSizeMeasuresStep(treeRootHolder, metricRepository, measureRepository, newLinesRepository, duplicationRepository); @Test public void compute_new_lines() { - setChangesets(FILE_1_REF, FILE_2_REF, FILE_4_REF); - + setNewLines(FILE_1, FILE_2, FILE_4); underTest.execute(new TestComputationStepContext()); assertRawMeasureValueOnPeriod(FILE_1_REF, NEW_LINES_KEY, 11); @@ -135,7 +130,7 @@ public class NewSizeMeasuresStepTest { @Test public void compute_new_lines_with_only_some_lines_having_changesets() { - setChangesetsForFirstThreeLines(FILE_1_REF, FILE_2_REF, FILE_4_REF); + setFirstTwoLinesAsNew(FILE_1, FILE_2, FILE_4); underTest.execute(new TestComputationStepContext()); @@ -161,7 +156,7 @@ public class NewSizeMeasuresStepTest { @Test public void compute_duplicated_lines_counts_lines_from_original_and_InnerDuplicate_of_a_single_line() { duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), new TextBlock(2, 2)); - setChangesets(FILE_1_REF); + setNewLines(FILE_1); underTest.execute(new TestComputationStepContext()); @@ -172,7 +167,7 @@ public class NewSizeMeasuresStepTest { public void compute_duplicated_lines_counts_lines_from_original_and_ignores_InProjectDuplicate() { TextBlock original = new TextBlock(1, 1); duplicationRepository.addDuplication(FILE_1_REF, original, FILE_2_REF, new TextBlock(2, 2)); - setChangesets(FILE_1_REF); + setNewLines(FILE_1); underTest.execute(new TestComputationStepContext()); @@ -183,7 +178,7 @@ public class NewSizeMeasuresStepTest { public void compute_duplicated_lines_counts_lines_from_original_and_ignores_CrossProjectDuplicate() { TextBlock original = new TextBlock(1, 1); duplicationRepository.addDuplication(FILE_1_REF, original, SOME_FILE_KEY, new TextBlock(2, 2)); - setChangesets(FILE_1_REF); + setNewLines(FILE_1); underTest.execute(new TestComputationStepContext()); @@ -194,7 +189,7 @@ public class NewSizeMeasuresStepTest { public void compute_duplicated_lines_counts_lines_from_original_and_InnerDuplicate() { TextBlock original = new TextBlock(1, 5); duplicationRepository.addDuplication(FILE_1_REF, original, new TextBlock(10, 11)); - setChangesets(FILE_1_REF); + setNewLines(FILE_1); underTest.execute(new TestComputationStepContext()); @@ -206,7 +201,7 @@ public class NewSizeMeasuresStepTest { TextBlock original = new TextBlock(1, 10); duplicationRepository.addDuplication(FILE_1_REF, original, new TextBlock(10, 11), new TextBlock(11, 12)); duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(2, 2), new TextBlock(4, 4)); - setChangesets(FILE_1_REF); + setNewLines(FILE_1); underTest.execute(new TestComputationStepContext()); @@ -218,10 +213,7 @@ public class NewSizeMeasuresStepTest { addDuplicatedBlock(FILE_1_REF, 2); addDuplicatedBlock(FILE_3_REF, 10); addDuplicatedBlock(FILE_4_REF, 12); - setChangesets(FILE_1_REF); - setChangesets(FILE_2_REF); - setChangesets(FILE_3_REF); - setChangesets(FILE_4_REF); + setNewLines(FILE_1, FILE_2, FILE_3, FILE_4); underTest.execute(new TestComputationStepContext()); @@ -243,10 +235,7 @@ public class NewSizeMeasuresStepTest { addDuplicatedBlock(FILE_1_REF, 2); addDuplicatedBlock(FILE_3_REF, 10); addDuplicatedBlock(FILE_4_REF, 12); - setChangesetsForFirstThreeLines(FILE_1_REF); - setChangesetsForFirstThreeLines(FILE_2_REF); - setChangesetsForFirstThreeLines(FILE_3_REF); - setChangesetsForFirstThreeLines(FILE_4_REF); + setFirstTwoLinesAsNew(FILE_1, FILE_2, FILE_3, FILE_4); underTest.execute(new TestComputationStepContext()); @@ -264,10 +253,7 @@ public class NewSizeMeasuresStepTest { @Test public void compute_and_aggregate_zero_duplicated_line_when_no_duplication() { - setChangesets(FILE_1_REF); - setChangesets(FILE_2_REF); - setChangesets(FILE_3_REF); - setChangesets(FILE_4_REF); + setNewLines(FILE_1, FILE_2, FILE_3, FILE_4); underTest.execute(new TestComputationStepContext()); @@ -278,7 +264,7 @@ public class NewSizeMeasuresStepTest { public void compute_duplicated_blocks_one_for_original_one_for_each_InnerDuplicate() { TextBlock original = new TextBlock(1, 1); duplicationRepository.addDuplication(FILE_1_REF, original, new TextBlock(2, 2), new TextBlock(4, 4), new TextBlock(3, 4)); - setChangesets(FILE_1_REF); + setNewLines(FILE_1); underTest.execute(new TestComputationStepContext()); @@ -289,7 +275,7 @@ public class NewSizeMeasuresStepTest { public void compute_duplicated_blocks_does_not_count_blocks_only_once_it_assumes_consistency_from_duplication_data() { duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), new TextBlock(4, 4)); duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(2, 2), new TextBlock(4, 4)); - setChangesets(FILE_1_REF); + setNewLines(FILE_1); underTest.execute(new TestComputationStepContext()); @@ -299,7 +285,7 @@ public class NewSizeMeasuresStepTest { @Test public void compute_duplicated_blocks_one_for_original_and_ignores_InProjectDuplicate() { duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), FILE_2_REF, new TextBlock(2, 2)); - setChangesets(FILE_1_REF); + setNewLines(FILE_1); underTest.execute(new TestComputationStepContext()); @@ -309,7 +295,7 @@ public class NewSizeMeasuresStepTest { @Test public void compute_duplicated_blocks_one_for_original_and_ignores_CrossProjectDuplicate() { duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), SOME_FILE_KEY, new TextBlock(2, 2)); - setChangesets(FILE_1_REF); + setNewLines(FILE_1); underTest.execute(new TestComputationStepContext()); @@ -321,7 +307,7 @@ public class NewSizeMeasuresStepTest { addDuplicatedBlock(FILE_1_REF, 11); addDuplicatedBlock(FILE_2_REF, 2); addDuplicatedBlock(FILE_4_REF, 7); - setChangesets(FILE_1_REF, FILE_2_REF, FILE_3_REF, FILE_4_REF); + setNewLines(FILE_1, FILE_2, FILE_3, FILE_4); underTest.execute(new TestComputationStepContext()); @@ -338,7 +324,7 @@ public class NewSizeMeasuresStepTest { @Test public void compute_and_aggregate_duplicated_blocks_to_zero_when_no_duplication() { - setChangesets(FILE_1_REF, FILE_2_REF, FILE_3_REF, FILE_4_REF); + setNewLines(FILE_1, FILE_2, FILE_3, FILE_4); underTest.execute(new TestComputationStepContext()); @@ -347,7 +333,7 @@ public class NewSizeMeasuresStepTest { @Test public void compute_new_duplicated_lines_density() { - setChangesets(FILE_1_REF, FILE_2_REF, FILE_4_REF); + setNewLines(FILE_1, FILE_2, FILE_4); addDuplicatedBlock(FILE_1_REF, 2); addDuplicatedBlock(FILE_3_REF, 10); addDuplicatedBlock(FILE_4_REF, 12); @@ -375,7 +361,6 @@ public class NewSizeMeasuresStepTest { /** * Adds duplication blocks of a single line (each line is specific to its block). - * * This is a very simple use case, convenient for unit tests but more realistic and complex use cases must be tested separately. */ private void addDuplicatedBlock(int fileRef, int blockCount) { @@ -388,31 +373,20 @@ public class NewSizeMeasuresStepTest { duplicationRepository.addDuplication(fileRef, original, duplicates); } - private void setChangesetsForFirstThreeLines(int... componentRefs) { - Arrays.stream(componentRefs) - .forEach(componentRef -> scmInfoRepository.setScmInfo(componentRef, - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - // line 3 is older, part of no period - Changeset.newChangesetBuilder().setDate(parseDate("2007-01-15").getTime()).setRevision("rev-2").build())); + private void setFirstTwoLinesAsNew(Component... components) { + when(newLinesRepository.newLinesAvailable()).thenReturn(true); + Set<Integer> newLines = new HashSet<>(Arrays.asList(1, 2)); + for (Component c : components) { + when(newLinesRepository.getNewLines(c)).thenReturn(Optional.of(newLines)); + } } - private void setChangesets(int... componentRefs) { - Arrays.stream(componentRefs) - .forEach(componentRef -> scmInfoRepository.setScmInfo(componentRef, - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - // line 3 is older, part of no period - Changeset.newChangesetBuilder().setDate(parseDate("2007-01-15").getTime()).setRevision("rev-2").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build())); + private void setNewLines(Component... components) { + when(newLinesRepository.newLinesAvailable()).thenReturn(true); + Set<Integer> newLines = new HashSet<>(Arrays.asList(1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12)); + for (Component c : components) { + when(newLinesRepository.getNewLines(c)).thenReturn(Optional.of(newLines)); + } } private void assertRawMeasureValueOnPeriod(int componentRef, String metricKey, double expectedVariation) { diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportNewCoverageMeasuresStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportNewCoverageMeasuresStepTest.java index 6fe3ec3571c..cb4a3ce600b 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportNewCoverageMeasuresStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportNewCoverageMeasuresStepTest.java @@ -19,7 +19,11 @@ */ package org.sonar.ce.task.projectanalysis.step; -import org.junit.Before; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; import org.junit.Rule; import org.junit.Test; import org.sonar.api.measures.CoreMetrics; @@ -32,14 +36,14 @@ import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepoEntry; import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule; import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule; import org.sonar.ce.task.projectanalysis.scm.Changeset; -import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryRule; +import org.sonar.ce.task.projectanalysis.source.NewLinesRepository; import org.sonar.ce.task.step.TestComputationStepContext; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.guava.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static org.sonar.api.measures.CoreMetrics.CONDITIONS_BY_LINE_KEY; import static org.sonar.api.measures.CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY; import static org.sonar.api.measures.CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY; @@ -67,6 +71,9 @@ public class ReportNewCoverageMeasuresStepTest { private static final int DIRECTORY_2_REF = 1112; private static final int FILE_2_REF = 11121; private static final int FILE_3_REF = 11122; + private static final Component FILE_1 = builder(FILE, FILE_1_REF).build(); + private static final Component FILE_2 = builder(FILE, FILE_2_REF).build(); + private static final Component FILE_3 = builder(FILE, FILE_3_REF).build(); private static final ReportComponent MULTIPLE_FILES_TREE = builder(PROJECT, ROOT_REF) .addChildren( @@ -75,25 +82,18 @@ public class ReportNewCoverageMeasuresStepTest { builder(MODULE, SUB_MODULE_REF) .addChildren( builder(DIRECTORY, DIRECTORY_1_REF) - .addChildren( - builder(FILE, FILE_1_REF).build()) + .addChildren(FILE_1) .build(), builder(DIRECTORY, DIRECTORY_2_REF) - .addChildren( - builder(FILE, FILE_2_REF).build(), - builder(FILE, FILE_3_REF).build()) + .addChildren(FILE_2, FILE_3) .build()) .build()) .build()) .build(); @Rule - public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule(); - @Rule public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); @Rule - public PeriodHolderRule periodsHolder = new PeriodHolderRule(); - @Rule public MetricRepositoryRule metricRepository = new MetricRepositoryRule() .add(CoreMetrics.COVERAGE_LINE_HITS_DATA) .add(CoreMetrics.CONDITIONS_BY_LINE) @@ -108,16 +108,11 @@ public class ReportNewCoverageMeasuresStepTest { @Rule public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - - private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, periodsHolder, measureRepository, metricRepository, scmInfoRepository); + private NewLinesRepository newLinesRepository = mock(NewLinesRepository.class); + private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, measureRepository, metricRepository, newLinesRepository); public static final ReportComponent FILE_COMPONENT = ReportComponent.builder(Component.Type.FILE, FILE_1_REF) .setFileAttributes(new FileAttributes(false, null, 1)).build(); - @Before - public void setUp() { - periodsHolder.setPeriod(new Period("mode_p_1", null, parseDate("2009-12-25").getTime(), "u1")); - } - @Test public void no_measure_for_PROJECT_component() { treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, ROOT_REF).build()); @@ -166,13 +161,8 @@ public class ReportNewCoverageMeasuresStepTest { @Test public void zero_measures_when_nothing_has_changed() { treeRootHolder.setRoot(FILE_COMPONENT); - scmInfoRepository.setScmInfo(FILE_1_REF, - Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build()); - + when(newLinesRepository.newLinesAvailable()).thenReturn(true); + when(newLinesRepository.getNewLines(FILE_COMPONENT)).thenReturn(Optional.of(Collections.emptySet())); measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERAGE_LINE_HITS_DATA_KEY, newMeasureBuilder().create("2=1;3=1")); measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1")); measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERED_CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1")); @@ -185,9 +175,7 @@ public class ReportNewCoverageMeasuresStepTest { @Test public void zero_measures_for_FILE_component_without_CoverageData() { treeRootHolder.setRoot(FILE_COMPONENT); - scmInfoRepository.setScmInfo(FILE_1_REF, - Changeset.newChangesetBuilder().setDate(parseDate("2008-05-18").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2008-05-18").getTime()).setRevision("rev-1").build()); + setNewLines(FILE_1); underTest.execute(new TestComputationStepContext()); @@ -196,6 +184,8 @@ public class ReportNewCoverageMeasuresStepTest { @Test public void verify_computation_of_measures_for_new_lines_for_FILE() { + when(newLinesRepository.newLinesAvailable()).thenReturn(true); + String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY; String newLinesToCover = NEW_LINES_TO_COVER_KEY; String newUncoveredLines = NEW_UNCOVERED_LINES_KEY; @@ -209,11 +199,7 @@ public class ReportNewCoverageMeasuresStepTest { private void verify_computation_of_measures_for_new_lines(String coverageLineHitsData, String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) { treeRootHolder.setRoot(FILE_COMPONENT); - scmInfoRepository.setScmInfo(FILE_1_REF, - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2007-01-15").getTime()).setRevision("rev-2").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build()); + setNewLines(FILE_1, 1, 2, 4); measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=3")); @@ -228,6 +214,8 @@ public class ReportNewCoverageMeasuresStepTest { @Test public void verify_computation_of_measures_for_new_conditions_for_FILE() { + when(newLinesRepository.newLinesAvailable()).thenReturn(true); + String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY; String conditionsByLine = CONDITIONS_BY_LINE_KEY; String coveredConditionsByLine = COVERED_CONDITIONS_BY_LINE_KEY; @@ -242,6 +230,8 @@ public class ReportNewCoverageMeasuresStepTest { @Test public void verify_aggregation_of_measures_for_new_conditions() { + when(newLinesRepository.newLinesAvailable()).thenReturn(true); + String coverageLineHitsData = CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY; String conditionsByLine = CoreMetrics.CONDITIONS_BY_LINE_KEY; String coveredConditionsByLine = CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY; @@ -254,9 +244,9 @@ public class ReportNewCoverageMeasuresStepTest { newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions); treeRootHolder.setRoot(MULTIPLE_FILES_TREE); - defineChangeSetsAndMeasures(FILE_1_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2)); - defineChangeSetsAndMeasures(FILE_2_REF, metricKeys, new MeasureValues(0, 14, 6), new MeasureValues(0, 13, 7)); - defineChangeSetsAndMeasures(FILE_3_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(1, 13, 7)); + defineNewLinesAndMeasures(FILE_1, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2)); + defineNewLinesAndMeasures(FILE_2, metricKeys, new MeasureValues(0, 14, 6), new MeasureValues(0, 13, 7)); + defineNewLinesAndMeasures(FILE_3, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(1, 13, 7)); underTest.execute(new TestComputationStepContext()); @@ -365,19 +355,11 @@ public class ReportNewCoverageMeasuresStepTest { entryOf(NEW_UNCOVERED_CONDITIONS_KEY, createMeasure(0d))); } - private void defineChangeSetsAndMeasures(int componentRef, MetricKeys metricKeys, MeasureValues line4, MeasureValues line6) { - scmInfoRepository.setScmInfo(componentRef, - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2007-01-15").getTime()).setRevision("rev-2").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2012-02-23").getTime()).setRevision("rev-3").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2012-02-23").getTime()).setRevision("rev-3").build(), - Changeset.newChangesetBuilder().setDate(parseDate("2012-02-23").getTime()).setRevision("rev-3").build()); - - measureRepository.addRawMeasure(componentRef, metricKeys.coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=" + line4.lineHits + ";5=1;6=" + line6.lineHits + ";7=0")); - measureRepository.addRawMeasure(componentRef, metricKeys.conditionsByLine, newMeasureBuilder().create("4=" + line4.coveredConditions + ";6=" + line6.coveredConditions)); - measureRepository.addRawMeasure(componentRef, metricKeys.coveredConditionsByLine, + private void defineNewLinesAndMeasures(Component c, MetricKeys metricKeys, MeasureValues line4, MeasureValues line6) { + setNewLines(c, 1, 2, 4,5,6,7); + measureRepository.addRawMeasure(c.getReportAttributes().getRef(), metricKeys.coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=" + line4.lineHits + ";5=1;6=" + line6.lineHits + ";7=0")); + measureRepository.addRawMeasure(c.getReportAttributes().getRef(), metricKeys.conditionsByLine, newMeasureBuilder().create("4=" + line4.coveredConditions + ";6=" + line6.coveredConditions)); + measureRepository.addRawMeasure(c.getReportAttributes().getRef(), metricKeys.coveredConditionsByLine, newMeasureBuilder().create("4=" + line4.uncoveredConditions + ";6=" + line6.uncoveredConditions)); } @@ -416,7 +398,7 @@ public class ReportNewCoverageMeasuresStepTest { private void verify_computation_of_measures_for_new_conditions(MetricKeys metricKeys) { treeRootHolder.setRoot(FILE_COMPONENT); - defineChangeSetsAndMeasures(FILE_COMPONENT.getReportAttributes().getRef(), metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2)); + defineNewLinesAndMeasures(FILE_COMPONENT, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2)); underTest.execute(new TestComputationStepContext()); @@ -433,4 +415,9 @@ public class ReportNewCoverageMeasuresStepTest { .createNoValue(); } + private void setNewLines(Component c, Integer... lines) { + when(newLinesRepository.newLinesAvailable()).thenReturn(true); + Set<Integer> newLines = new HashSet<>(Arrays.asList(lines)); + when(newLinesRepository.getNewLines(c)).thenReturn(Optional.of(newLines)); + } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsNewCoverageMeasuresStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsNewCoverageMeasuresStepTest.java index 0e93781e7c7..f655c5f8f97 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsNewCoverageMeasuresStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsNewCoverageMeasuresStepTest.java @@ -19,7 +19,6 @@ */ package org.sonar.ce.task.projectanalysis.step; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.sonar.api.measures.CoreMetrics; @@ -29,13 +28,12 @@ import org.sonar.ce.task.projectanalysis.formula.coverage.LinesAndConditionsWith import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule; import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.ce.task.projectanalysis.period.Period; -import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule; +import org.sonar.ce.task.projectanalysis.source.NewLinesRepository; import org.sonar.ce.task.step.TestComputationStepContext; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.guava.api.Assertions.assertThat; -import static org.sonar.api.utils.DateUtils.parseDate; +import static org.mockito.Mockito.mock; import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT_VIEW; import static org.sonar.ce.task.projectanalysis.component.Component.Type.SUBVIEW; import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW; @@ -74,8 +72,7 @@ public class ViewsNewCoverageMeasuresStepTest { @Rule public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); - @Rule - public PeriodHolderRule periodsHolder = new PeriodHolderRule(); + @Rule public MetricRepositoryRule metricRepository = new MetricRepositoryRule() .add(CoreMetrics.COVERAGE_LINE_HITS_DATA) @@ -91,13 +88,7 @@ public class ViewsNewCoverageMeasuresStepTest { @Rule public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, periodsHolder, - measureRepository, metricRepository); - - @Before - public void setUp() { - periodsHolder.setPeriod(new Period("mode_p_1", null, parseDate("2009-12-25").getTime(), "U1")); - } + private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, measureRepository, metricRepository); @Test public void verify_aggregation_of_measures_for_new_conditions() { |