Skip to content

Commit

Permalink
SONAR-6397 Use ScmInfoRepo in SqaleNewMeasuresVisitor
Browse files Browse the repository at this point in the history
  • Loading branch information
julienlancelot committed Oct 2, 2015
1 parent 9b8a443 commit 38a386c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 71 deletions.
Expand Up @@ -29,8 +29,6 @@
import org.sonar.api.utils.KeyValueFormat; import org.sonar.api.utils.KeyValueFormat;
import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Loggers;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component; import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.CrawlerDepthLimit; import org.sonar.server.computation.component.CrawlerDepthLimit;
import org.sonar.server.computation.component.PathAwareVisitorAdapter; import org.sonar.server.computation.component.PathAwareVisitorAdapter;
Expand All @@ -42,6 +40,9 @@
import org.sonar.server.computation.metric.MetricRepository; import org.sonar.server.computation.metric.MetricRepository;
import org.sonar.server.computation.period.Period; import org.sonar.server.computation.period.Period;
import org.sonar.server.computation.period.PeriodsHolder; import org.sonar.server.computation.period.PeriodsHolder;
import org.sonar.server.computation.scm.Changeset;
import org.sonar.server.computation.scm.ScmInfo;
import org.sonar.server.computation.scm.ScmInfoRepository;


import static com.google.common.collect.FluentIterable.from; import static com.google.common.collect.FluentIterable.from;
import static org.sonar.api.utils.KeyValueFormat.newIntegerConverter; import static org.sonar.api.utils.KeyValueFormat.newIntegerConverter;
Expand All @@ -56,7 +57,7 @@
public class SqaleNewMeasuresVisitor extends PathAwareVisitorAdapter<SqaleNewMeasuresVisitor.NewDevelopmentCostCounter> { public class SqaleNewMeasuresVisitor extends PathAwareVisitorAdapter<SqaleNewMeasuresVisitor.NewDevelopmentCostCounter> {
private static final Logger LOG = Loggers.get(SqaleNewMeasuresVisitor.class); private static final Logger LOG = Loggers.get(SqaleNewMeasuresVisitor.class);


private final BatchReportReader batchReportReader; private final ScmInfoRepository scmInfoRepository;
private final MeasureRepository measureRepository; private final MeasureRepository measureRepository;
private final PeriodsHolder periodsHolder; private final PeriodsHolder periodsHolder;
private final SqaleRatingSettings sqaleRatingSettings; private final SqaleRatingSettings sqaleRatingSettings;
Expand All @@ -65,11 +66,11 @@ public class SqaleNewMeasuresVisitor extends PathAwareVisitorAdapter<SqaleNewMea
private final Metric nclocDataMetric; private final Metric nclocDataMetric;
private final Metric newDebtRatioMetric; private final Metric newDebtRatioMetric;


public SqaleNewMeasuresVisitor(MetricRepository metricRepository, MeasureRepository measureRepository, BatchReportReader batchReportReader, PeriodsHolder periodsHolder, public SqaleNewMeasuresVisitor(MetricRepository metricRepository, MeasureRepository measureRepository, ScmInfoRepository scmInfoRepository, PeriodsHolder periodsHolder,
SqaleRatingSettings sqaleRatingSettings) { SqaleRatingSettings sqaleRatingSettings) {
super(CrawlerDepthLimit.FILE, POST_ORDER, NewDevelopmentCostCounterFactory.INSTANCE); super(CrawlerDepthLimit.FILE, POST_ORDER, NewDevelopmentCostCounterFactory.INSTANCE);
this.batchReportReader = batchReportReader;
this.measureRepository = measureRepository; this.measureRepository = measureRepository;
this.scmInfoRepository = scmInfoRepository;
this.periodsHolder = periodsHolder; this.periodsHolder = periodsHolder;
this.sqaleRatingSettings = sqaleRatingSettings; this.sqaleRatingSettings = sqaleRatingSettings;


Expand Down Expand Up @@ -155,25 +156,20 @@ private void initNewDebtRatioCounter(Component file, Path<NewDevelopmentCostCoun
return; return;
} }


BatchReport.Changesets changesets = batchReportReader.readChangesets(file.getReportAttributes().getRef()); Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(file);
if (changesets == null) { if (!scmInfoOptional.isPresent()) {
LOG.trace(String.format("No changeset for file %s. Dev cost will be zero.", file.getKey())); LOG.trace(String.format("No changeset for file %s. Dev cost will be zero.", file.getKey()));
return; return;
} }


initNewDebtRatioCounter(path.current(), file.getFileAttributes().getLanguageKey(), nclocDataMeasure.get(), changesets); ScmInfo scmInfo = scmInfoOptional.get();
initNewDebtRatioCounter(path.current(), file.getFileAttributes().getLanguageKey(), nclocDataMeasure.get(), scmInfo);
} }


private void initNewDebtRatioCounter(NewDevelopmentCostCounter devCostCounter, String languageKey, Measure nclocDataMeasure, BatchReport.Changesets changesets) { private void initNewDebtRatioCounter(NewDevelopmentCostCounter devCostCounter, String languageKey, Measure nclocDataMeasure, ScmInfo scmInfo) {
long lineDevCost = sqaleRatingSettings.getDevCost(languageKey); long lineDevCost = sqaleRatingSettings.getDevCost(languageKey);
for (Integer nclocLineIndex : nclocLineIndexes(nclocDataMeasure)) { for (Integer nclocLineIndex : nclocLineIndexes(nclocDataMeasure)) {
// lines are 0-based in changesetIndexByLine array Changeset changeset = scmInfo.getChangesetForLine(nclocLineIndex);
int changesetIndex = changesets.getChangesetIndexByLine(nclocLineIndex - 1);
BatchReport.Changesets.Changeset changeset = changesets.getChangeset(changesetIndex);
if (!changeset.hasDate()) {
continue;
}

for (Period period : periodsHolder.getPeriods()) { for (Period period : periodsHolder.getPeriods()) {
if (isLineInPeriod(changeset.getDate(), period)) { if (isLineInPeriod(changeset.getDate(), period)) {
devCostCounter.increment(period, lineDevCost); devCostCounter.increment(period, lineDevCost);
Expand Down
Expand Up @@ -30,8 +30,6 @@
import org.junit.Test; import org.junit.Test;
import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.KeyValueFormat; import org.sonar.api.utils.KeyValueFormat;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.batch.TreeRootHolderRule; import org.sonar.server.computation.batch.TreeRootHolderRule;
import org.sonar.server.computation.component.Component; import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ComponentVisitor; import org.sonar.server.computation.component.ComponentVisitor;
Expand All @@ -44,6 +42,8 @@
import org.sonar.server.computation.metric.MetricRepositoryRule; import org.sonar.server.computation.metric.MetricRepositoryRule;
import org.sonar.server.computation.period.Period; import org.sonar.server.computation.period.Period;
import org.sonar.server.computation.period.PeriodsHolderRule; import org.sonar.server.computation.period.PeriodsHolderRule;
import org.sonar.server.computation.scm.Changeset;
import org.sonar.server.computation.scm.ScmInfoRepositoryRule;


import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
Expand All @@ -69,7 +69,7 @@ public class SqaleNewMeasuresVisitorTest {
private static final Offset<Double> VARIATION_COMPARISON_OFFSET = Offset.offset(0.01); private static final Offset<Double> VARIATION_COMPARISON_OFFSET = Offset.offset(0.01);


@Rule @Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule(); public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule();
@Rule @Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
@Rule @Rule
Expand All @@ -84,7 +84,7 @@ public class SqaleNewMeasuresVisitorTest {


private SqaleRatingSettings sqaleRatingSettings = mock(SqaleRatingSettings.class); private SqaleRatingSettings sqaleRatingSettings = mock(SqaleRatingSettings.class);


private VisitorsCrawler underTest = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(new SqaleNewMeasuresVisitor(metricRepository, measureRepository, reportReader, private VisitorsCrawler underTest = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(new SqaleNewMeasuresVisitor(metricRepository, measureRepository, scmInfoRepository,
periodsHolder, sqaleRatingSettings))); periodsHolder, sqaleRatingSettings)));


@Before @Before
Expand Down Expand Up @@ -136,7 +136,7 @@ public void file_has_0_new_debt_ratio_if_all_scm_dates_are_before_snapshot_dates
); );
measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50, 12)); measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50, 12));
measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4)); measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4));
reportReader.putChangesets(createChangesets(LANGUAGE_1_FILE_REF, PERIOD_2_SNAPSHOT_DATE - 100, 4)); scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_2_SNAPSHOT_DATE - 100, 4));


underTest.visit(treeRootHolder.getRoot()); underTest.visit(treeRootHolder.getRoot());


Expand Down Expand Up @@ -199,17 +199,6 @@ public void new_debt_ratio_is_0_when_file_has_no_changesets() {
assertNewDebtRatioValues(ROOT_REF, 0, 0); assertNewDebtRatioValues(ROOT_REF, 0, 0);
} }


@Test
public void new_debt_ratio_is_0_when_file_has_empty_changesets() {
when(sqaleRatingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
setupOneFileAloneInAProject(50, 12, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_DATE_CHANGESET);

underTest.visit(treeRootHolder.getRoot());

assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 0, 0);
assertNewDebtRatioValues(ROOT_REF, 0, 0);
}

@Test @Test
public void new_debt_ratio_is_0_when_there_is_no_ncloc_in_file() { public void new_debt_ratio_is_0_when_there_is_no_ncloc_in_file() {
when(sqaleRatingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST); when(sqaleRatingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
Expand Down Expand Up @@ -256,7 +245,7 @@ public void no_leaf_components_always_have_a_measure_when_at_least_one_period_ex
// 4 lines file, only first one is not ncloc // 4 lines file, only first one is not ncloc
measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4)); 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 // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date
reportReader.putChangesets(createChangesets(LANGUAGE_1_FILE_REF, PERIOD_2_SNAPSHOT_DATE - 100, 2, PERIOD_2_SNAPSHOT_DATE + 100, 2)); scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_2_SNAPSHOT_DATE - 100, 2, PERIOD_2_SNAPSHOT_DATE + 100, 2));


underTest.visit(treeRootHolder.getRoot()); underTest.visit(treeRootHolder.getRoot());


Expand All @@ -269,7 +258,7 @@ public void no_leaf_components_always_have_a_measure_when_at_least_one_period_ex
private void setupOneFileAloneInAProject(int newDebtPeriod2, int newDebtPeriod4, Flag isUnitTest, Flag withNclocLines, Flag withChangeSets) { private void setupOneFileAloneInAProject(int newDebtPeriod2, int newDebtPeriod4, Flag isUnitTest, Flag withNclocLines, Flag withChangeSets) {
checkArgument(isUnitTest == Flag.UT_FILE || isUnitTest == Flag.SRC_FILE); checkArgument(isUnitTest == Flag.UT_FILE || isUnitTest == Flag.SRC_FILE);
checkArgument(withNclocLines == Flag.WITH_NCLOC || withNclocLines == Flag.NO_NCLOC || withNclocLines == Flag.MISSING_MEASURE_NCLOC); checkArgument(withNclocLines == Flag.WITH_NCLOC || withNclocLines == Flag.NO_NCLOC || withNclocLines == Flag.MISSING_MEASURE_NCLOC);
checkArgument(withChangeSets == Flag.WITH_CHANGESET || withChangeSets == Flag.NO_CHANGESET || withChangeSets == Flag.NO_DATE_CHANGESET); checkArgument(withChangeSets == Flag.WITH_CHANGESET || withChangeSets == Flag.NO_CHANGESET);


treeRootHolder.setRoot( treeRootHolder.setRoot(
builder(PROJECT, ROOT_REF) builder(PROJECT, ROOT_REF)
Expand All @@ -291,14 +280,12 @@ private void setupOneFileAloneInAProject(int newDebtPeriod2, int newDebtPeriod4,
} }
if (withChangeSets == Flag.WITH_CHANGESET) { if (withChangeSets == Flag.WITH_CHANGESET) {
// first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date
reportReader.putChangesets(createChangesets(LANGUAGE_1_FILE_REF, PERIOD_2_SNAPSHOT_DATE - 100, 2, PERIOD_2_SNAPSHOT_DATE + 100, 2)); scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_2_SNAPSHOT_DATE - 100, 2, PERIOD_2_SNAPSHOT_DATE + 100, 2));
} else if (withChangeSets == Flag.NO_DATE_CHANGESET) {
reportReader.putChangesets(createNoDateChangesets(LANGUAGE_1_FILE_REF, 4));
} }
} }


private enum Flag { private enum Flag {
UT_FILE, SRC_FILE, NO_CHANGESET, WITH_CHANGESET, NO_DATE_CHANGESET, WITH_NCLOC, NO_NCLOC, MISSING_MEASURE_NCLOC UT_FILE, SRC_FILE, NO_CHANGESET, WITH_CHANGESET, WITH_NCLOC, NO_NCLOC, MISSING_MEASURE_NCLOC
} }


public static ReportComponent.Builder builder(Component.Type type, int ref) { public static ReportComponent.Builder builder(Component.Type type, int ref) {
Expand Down Expand Up @@ -328,48 +315,32 @@ private static Measure createNoNclocDataMeasure(int lineCount) {
} }


/** /**
* Creates a changeset of {@code lines} lines which all have the same date {@code scmDate}. * Creates changesets of {@code lines} lines which all have the same date {@code scmDate}.
*/ */
private static BatchReport.Changesets createChangesets(int componentRef, long scmDate, int lines) { private static Changeset[] createChangesets(long scmDate, int lines) {
BatchReport.Changesets.Builder builder = BatchReport.Changesets.newBuilder() Changeset changetset = Changeset.newChangesetBuilder().setDate(scmDate).setRevision("rev-1").build();
.setComponentRef(componentRef); Changeset[] changesets = new Changeset[lines];
addChangeSet(builder, scmDate, lines); for (int i = 0; i < lines; i++) {
return builder.build(); changesets[i] = changetset;
}
return changesets;
} }


/** /**
* Creates a changeset of {@code lineCount} lines which have the date {@code scmDate} and {@code otherLineCount} lines which * Creates a changeset of {@code lineCount} lines which have the date {@code scmDate} and {@code otherLineCount} lines which
* have the date {@code otherScmDate}. * have the date {@code otherScmDate}.
*/ */
private static BatchReport.Changesets createChangesets(int componentRef, long scmDate, int lineCount, long otherScmDate, int otherLineCount) { private static Changeset[] createChangesets(long scmDate, int lineCount, long otherScmDate, int otherLineCount) {
BatchReport.Changesets.Builder builder = BatchReport.Changesets.newBuilder() Changeset[] changesets = new Changeset[lineCount + otherLineCount];
.setComponentRef(componentRef); Changeset changetset1 = Changeset.newChangesetBuilder().setDate(scmDate).setRevision("rev-1").build();
addChangeSet(builder, scmDate, lineCount);
addChangeSet(builder, otherScmDate, otherLineCount);
return builder.build();
}

private static void addChangeSet(BatchReport.Changesets.Builder builder, long scmDate, int lines) {
BatchReport.Changesets.Changeset.Builder changesetBuilder = BatchReport.Changesets.Changeset.newBuilder();
changesetBuilder.setRevision("rev" + scmDate);
changesetBuilder.setDate(scmDate);
builder.addChangeset(changesetBuilder.build());
for (int i = 0; i < lines; i++) {
builder.addChangesetIndexByLine(builder.getChangesetCount() - 1);
}
}

private BatchReport.Changesets createNoDateChangesets(int componentRef, int lineCount) {
BatchReport.Changesets.Builder builder = BatchReport.Changesets.newBuilder().setComponentRef(componentRef);

BatchReport.Changesets.Changeset.Builder changesetBuilder = BatchReport.Changesets.Changeset.newBuilder();
changesetBuilder.setRevision("rev");
builder.addChangeset(changesetBuilder.build());
for (int i = 0; i < lineCount; i++) { for (int i = 0; i < lineCount; i++) {
builder.addChangesetIndexByLine(builder.getChangesetCount() - 1); changesets[i] = changetset1;
} }

Changeset changetset2 = Changeset.newChangesetBuilder().setDate(otherScmDate).setRevision("rev-2").build();
return builder.build(); for (int i = lineCount; i < lineCount + otherLineCount; i++) {
changesets[i] = changetset2;
}
return changesets;
} }


private void assertNoNewDebtRatioMeasure(int componentRef) { private void assertNoNewDebtRatioMeasure(int componentRef) {
Expand Down

0 comments on commit 38a386c

Please sign in to comment.