@@ -30,6 +30,7 @@ import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.SnapshotDto; | |||
import org.sonar.scanner.protocol.output.ScannerReport; | |||
import static com.google.common.base.Preconditions.checkArgument; | |||
import static com.google.common.collect.Iterables.toArray; | |||
import static java.lang.String.format; | |||
import static org.apache.commons.lang.StringUtils.trimToNull; | |||
@@ -189,6 +190,7 @@ public class ComponentRootBuilder { | |||
return null; | |||
} | |||
checkArgument(component.getLines() > 0, "File '%s' has no line", component.getPath()); | |||
return new FileAttributes( | |||
component.getIsTest(), | |||
trimToNull(component.getLanguage()), |
@@ -38,7 +38,7 @@ public class FileAttributes { | |||
public FileAttributes(boolean unitTest, @Nullable String languageKey, int lines) { | |||
this.unitTest = unitTest; | |||
this.languageKey = languageKey; | |||
checkArgument(lines > 0, "Lines has not been set for this file"); | |||
checkArgument(lines > 0, "Number of lines must be greater than zero"); | |||
this.lines = lines; | |||
} | |||
@@ -51,6 +51,9 @@ public class FileAttributes { | |||
return languageKey; | |||
} | |||
/** | |||
* Number of lines of the file, can never be less than 1 | |||
*/ | |||
public int getLines() { | |||
return lines; | |||
} |
@@ -22,7 +22,6 @@ package org.sonar.server.computation.task.projectanalysis.step; | |||
import com.google.common.base.Optional; | |||
import com.google.common.collect.ImmutableList; | |||
import java.util.List; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.server.computation.task.projectanalysis.component.Component; | |||
import org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit; | |||
import org.sonar.server.computation.task.projectanalysis.component.PathAwareCrawler; | |||
@@ -38,6 +37,8 @@ import org.sonar.server.computation.task.step.ComputationStep; | |||
import static org.sonar.api.measures.CoreMetrics.ACCESSORS_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.DIRECTORIES_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.FILES_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.FUNCTIONS_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.GENERATED_LINES_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.GENERATED_NCLOC_KEY; | |||
@@ -54,7 +55,6 @@ import static org.sonar.server.computation.task.projectanalysis.measure.Measure. | |||
public class SizeMeasuresStep implements ComputationStep { | |||
private static final CounterStackElementFactory COUNTER_STACK_ELEMENT_FACTORY = new CounterStackElementFactory(); | |||
private static final List<Formula> AGGREGATED_SIZE_MEASURE_FORMULAS = ImmutableList.<Formula>of( | |||
createIntSumFormula(LINES_KEY), | |||
createIntSumFormula(GENERATED_LINES_KEY), | |||
createIntSumFormula(NCLOC_KEY), | |||
createIntSumFormula(GENERATED_NCLOC_KEY), | |||
@@ -75,11 +75,11 @@ public class SizeMeasuresStep implements ComputationStep { | |||
@Override | |||
public void execute() { | |||
Metric fileMetric = metricRepository.getByKey(CoreMetrics.FILES_KEY); | |||
Metric directoryMetric = metricRepository.getByKey(CoreMetrics.DIRECTORIES_KEY); | |||
new PathAwareCrawler<>(new FileAndDirectoryMeasureVisitor(directoryMetric, fileMetric)) | |||
.visit(treeRootHolder.getRoot()); | |||
new PathAwareCrawler<>(new FileAndDirectoryMeasureVisitor( | |||
metricRepository.getByKey(DIRECTORIES_KEY), | |||
metricRepository.getByKey(FILES_KEY), | |||
metricRepository.getByKey(LINES_KEY))) | |||
.visit(treeRootHolder.getRoot()); | |||
new PathAwareCrawler<>(FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository) | |||
.buildFor(AGGREGATED_SIZE_MEASURE_FORMULAS)) | |||
.visit(treeRootHolder.getRoot()); | |||
@@ -93,40 +93,44 @@ public class SizeMeasuresStep implements ComputationStep { | |||
private class FileAndDirectoryMeasureVisitor extends PathAwareVisitorAdapter<Counter> { | |||
private final Metric directoryMetric; | |||
private final Metric fileMetric; | |||
private final Metric linesMetric; | |||
public FileAndDirectoryMeasureVisitor(Metric directoryMetric, Metric fileMetric) { | |||
public FileAndDirectoryMeasureVisitor(Metric directoryMetric, Metric fileMetric, Metric linesMetric) { | |||
super(CrawlerDepthLimit.LEAVES, POST_ORDER, COUNTER_STACK_ELEMENT_FACTORY); | |||
this.directoryMetric = directoryMetric; | |||
this.fileMetric = fileMetric; | |||
this.linesMetric = linesMetric; | |||
} | |||
@Override | |||
public void visitProject(Component project, Path<Counter> path) { | |||
createMeasures(project, path.current().directories, path.current().files); | |||
createMeasures(project, path.current()); | |||
} | |||
@Override | |||
public void visitModule(Component module, Path<Counter> path) { | |||
createMeasures(module, path.current().directories, path.current().files); | |||
path.parent().directories += path.current().directories; | |||
path.parent().files += path.current().files; | |||
createMeasures(module, path.current()); | |||
path.parent().aggregate(path.current()); | |||
} | |||
@Override | |||
public void visitDirectory(Component directory, Path<Counter> path) { | |||
int fileCount = path.current().files; | |||
if (fileCount > 0) { | |||
createMeasures(directory, 1, fileCount); | |||
measureRepository.add(directory, directoryMetric, newMeasureBuilder().create(1)); | |||
measureRepository.add(directory, fileMetric, newMeasureBuilder().create(fileCount)); | |||
measureRepository.add(directory, linesMetric, newMeasureBuilder().create(path.current().lines)); | |||
path.parent().directories += 1; | |||
path.parent().files += fileCount; | |||
path.parent().lines += path.current().lines; | |||
} | |||
} | |||
private void createMeasures(Component directory, int dirCount, int fileCount) { | |||
if (fileCount > 0) { | |||
measureRepository.add(directory, directoryMetric, newMeasureBuilder().create(dirCount)); | |||
measureRepository.add(directory, fileMetric, newMeasureBuilder().create(fileCount)); | |||
private void createMeasures(Component directory, Counter counter) { | |||
if (counter.files > 0) { | |||
measureRepository.add(directory, directoryMetric, newMeasureBuilder().create(counter.directories)); | |||
measureRepository.add(directory, fileMetric, newMeasureBuilder().create(counter.files)); | |||
measureRepository.add(directory, linesMetric, newMeasureBuilder().create(counter.lines)); | |||
} | |||
} | |||
@@ -135,41 +139,47 @@ public class SizeMeasuresStep implements ComputationStep { | |||
if (file.getFileAttributes().isUnitTest()) { | |||
return; | |||
} | |||
int lines = file.getFileAttributes().getLines(); | |||
measureRepository.add(file, fileMetric, newMeasureBuilder().create(1)); | |||
measureRepository.add(file, linesMetric, newMeasureBuilder().create(lines)); | |||
path.parent().lines += lines; | |||
path.parent().files += 1; | |||
} | |||
@Override | |||
public void visitView(Component view, Path<Counter> path) { | |||
createMeasures(view, path.current().directories, path.current().files); | |||
createMeasures(view, path.current()); | |||
} | |||
@Override | |||
public void visitSubView(Component subView, Path<Counter> path) { | |||
createMeasures(subView, path.current().directories, path.current().files); | |||
path.parent().directories += path.current().directories; | |||
path.parent().files += path.current().files; | |||
createMeasures(subView, path.current()); | |||
path.parent().aggregate(path.current()); | |||
} | |||
@Override | |||
public void visitProjectView(Component projectView, Path<Counter> path) { | |||
path.parent().directories += getIntValue(projectView, this.directoryMetric); | |||
path.parent().files += getIntValue(projectView, this.fileMetric); | |||
path.parent().lines += getIntValue(projectView, this.linesMetric); | |||
} | |||
private int getIntValue(Component component, Metric metric) { | |||
Optional<Measure> fileMeasure = measureRepository.getRawMeasure(component, metric); | |||
return fileMeasure.isPresent() ? fileMeasure.get().getIntValue() : 0; | |||
} | |||
} | |||
private static class Counter { | |||
private int lines = 0; | |||
private int files = 0; | |||
private int directories = 0; | |||
void aggregate(Counter counter) { | |||
directories += counter.directories; | |||
files += counter.files; | |||
lines += counter.lines; | |||
} | |||
} | |||
private static class CounterStackElementFactory extends PathAwareVisitorAdapter.SimpleStackElementFactory<Counter> { | |||
@@ -188,4 +198,5 @@ public class SizeMeasuresStep implements ComputationStep { | |||
return null; | |||
} | |||
} | |||
} |
@@ -489,18 +489,25 @@ public class ComponentRootBuilderTest { | |||
assertThat(createFileAttributes(newBuilder().setType(FILE).setLines(10).build()).getLines()).isEqualTo(10); | |||
} | |||
@Test | |||
public void fail_with_IAE_when_createFileAttributes_lines_is_not_set() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("File 'src/main/java/Main.java' has no line"); | |||
createFileAttributes(newBuilder().setType(FILE).setPath("src/main/java/Main.java").build()); | |||
} | |||
@Test | |||
public void fail_with_IAE_when_createFileAttributes_sets_lines_to_0() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Lines has not been set for this file"); | |||
createFileAttributes(newBuilder().setType(FILE).setLines(0).build()); | |||
expectedException.expectMessage("File 'src/main/java/Main.java' has no line"); | |||
createFileAttributes(newBuilder().setType(FILE).setPath("src/main/java/Main.java").setLines(0).build()); | |||
} | |||
@Test | |||
public void fail_with_IAE_when_createFileAttributes_lines_is_not_set() throws Exception { | |||
public void fail_with_IAE_when_createFileAttributes_sets_lines_to_less_than_0() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Lines has not been set for this file"); | |||
createFileAttributes(newBuilder().setType(FILE).build()); | |||
expectedException.expectMessage("File 'src/main/java/Main.java' has no line"); | |||
createFileAttributes(newBuilder().setType(FILE).setPath("src/main/java/Main.java").setLines(-10).build()); | |||
} | |||
private static class ScannerComponentProvider extends ExternalResource implements Function<Integer, ScannerReport.Component> { |
@@ -0,0 +1,80 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact 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.server.computation.task.projectanalysis.component; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class FileAttributesTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Test | |||
public void create_production_file() throws Exception { | |||
FileAttributes underTest = new FileAttributes(true, "java", 10); | |||
assertThat(underTest.isUnitTest()).isTrue(); | |||
assertThat(underTest.getLanguageKey()).isEqualTo("java"); | |||
assertThat(underTest.getLines()).isEqualTo(10); | |||
} | |||
@Test | |||
public void create_unit_test() throws Exception { | |||
FileAttributes underTest = new FileAttributes(true, "java", 10); | |||
assertThat(underTest.isUnitTest()).isTrue(); | |||
assertThat(underTest.getLanguageKey()).isEqualTo("java"); | |||
assertThat(underTest.getLines()).isEqualTo(10); | |||
} | |||
@Test | |||
public void create_without_language() throws Exception { | |||
FileAttributes underTest = new FileAttributes(true, null, 10); | |||
assertThat(underTest.isUnitTest()).isTrue(); | |||
assertThat(underTest.getLanguageKey()).isNull(); | |||
assertThat(underTest.getLines()).isEqualTo(10); | |||
} | |||
@Test | |||
public void fail_with_IAE_when_lines_is_0() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Number of lines must be greater than zero"); | |||
new FileAttributes(true, "java", 0); | |||
} | |||
@Test | |||
public void fail_with_IAE_when_lines_is_less_than_0() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Number of lines must be greater than zero"); | |||
new FileAttributes(true, "java", -10); | |||
} | |||
@Test | |||
public void test_toString() throws Exception { | |||
assertThat(new FileAttributes(true, "java", 10).toString()).isEqualTo("FileAttributes{languageKey='java', unitTest=true, lines=10}"); | |||
assertThat(new FileAttributes(false, null, 1).toString()).isEqualTo("FileAttributes{languageKey='null', unitTest=false, lines=1}"); | |||
} | |||
} |
@@ -77,17 +77,17 @@ public class ReportSizeMeasuresStepTest { | |||
.addChildren( | |||
builder(DIRECTORY, DIRECTORY_1_REF) | |||
.addChildren( | |||
builder(FILE, FILE_1_REF).build(), | |||
builder(FILE, FILE_2_REF).build()) | |||
builder(FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_DOES_NOT_MATTER_HERE, 1)).build(), | |||
builder(FILE, FILE_2_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_DOES_NOT_MATTER_HERE, 2)).build()) | |||
.build(), | |||
builder(DIRECTORY, DIRECTORY_2_REF) | |||
.addChildren( | |||
builder(FILE, FILE_3_REF).build(), | |||
builder(FILE, UNIT_TEST_1_REF).setFileAttributes(new FileAttributes(true, LANGUAGE_DOES_NOT_MATTER_HERE, 1)).build()) | |||
builder(FILE, FILE_3_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_DOES_NOT_MATTER_HERE, 7)).build(), | |||
builder(FILE, UNIT_TEST_1_REF).setFileAttributes(new FileAttributes(true, LANGUAGE_DOES_NOT_MATTER_HERE, 4)).build()) | |||
.build(), | |||
builder(DIRECTORY, DIRECTORY_3_REF) | |||
.addChildren( | |||
builder(FILE, UNIT_TEST_2_REF).setFileAttributes(new FileAttributes(true, LANGUAGE_DOES_NOT_MATTER_HERE, 1)).build()) | |||
builder(FILE, UNIT_TEST_2_REF).setFileAttributes(new FileAttributes(true, LANGUAGE_DOES_NOT_MATTER_HERE, 10)).build()) | |||
.build()) | |||
.build()) | |||
.build()) | |||
@@ -110,25 +110,50 @@ public class ReportSizeMeasuresStepTest { | |||
private SizeMeasuresStep underTest = new SizeMeasuresStep(treeRootHolder, metricRepository, measureRepository); | |||
@Test | |||
public void verify_FILE_and_DIRECTORY_computation_and_aggregation() { | |||
public void verify_LINES_and_FILE_and_DIRECTORY_computation_and_aggregation() { | |||
underTest.execute(); | |||
verifyMeasuresOnFile(FILE_1_REF, 1); | |||
verifyMeasuresOnFile(FILE_2_REF, 1); | |||
verifyMeasuresOnFile(FILE_3_REF, 1); | |||
verifyMeasuresOnFile(FILE_1_REF, 1, 1); | |||
verifyMeasuresOnFile(FILE_2_REF, 2, 1); | |||
verifyMeasuresOnFile(FILE_3_REF, 7, 1); | |||
verifyNoMeasure(UNIT_TEST_1_REF); | |||
verifyNoMeasure(UNIT_TEST_2_REF); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_1_REF, 2, 1); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_2_REF, 1, 1); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_3_REF, NO_METRIC, NO_METRIC); | |||
verifyMeasuresOnOtherComponent(SUB_MODULE_REF, 3, 2); | |||
verifyMeasuresOnOtherComponent(MODULE_REF, 3, 2); | |||
verifyMeasuresOnOtherComponent(ROOT_REF, 3, 2); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_1_REF, 3, 2, 1); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_2_REF, 7, 1, 1); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_3_REF, NO_METRIC, NO_METRIC, NO_METRIC); | |||
verifyMeasuresOnOtherComponent(SUB_MODULE_REF, 10, 3, 2); | |||
verifyMeasuresOnOtherComponent(MODULE_REF, 10, 3, 2); | |||
verifyMeasuresOnOtherComponent(ROOT_REF, 10, 3, 2); | |||
} | |||
@Test | |||
public void verify_LINE_related_measures_aggregation() { | |||
verifyTwoMeasureAggregation(LINES_KEY, GENERATED_LINES_KEY); | |||
public void verify_GENERATED_LINES_related_measures_aggregation() { | |||
verifyMetricAggregation(GENERATED_LINES_KEY); | |||
} | |||
@Test | |||
public void verify_NCLOC_measure_aggregation() { | |||
verifyMetricAggregation(NCLOC_KEY); | |||
} | |||
private void verifyMetricAggregation(String metricKey) { | |||
measureRepository.addRawMeasure(FILE_1_REF, metricKey, newMeasureBuilder().create(10)); | |||
measureRepository.addRawMeasure(FILE_2_REF, metricKey, newMeasureBuilder().create(6)); | |||
measureRepository.addRawMeasure(UNIT_TEST_1_REF, metricKey, newMeasureBuilder().create(3)); | |||
underTest.execute(); | |||
verifyMeasuresOnFile(FILE_1_REF, 1, 1); | |||
verifyMeasuresOnFile(FILE_2_REF, 2, 1); | |||
verifyMeasuresOnFile(FILE_3_REF, 7, 1); | |||
verifyNoMeasure(UNIT_TEST_1_REF); | |||
verifyNoMeasure(UNIT_TEST_2_REF); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_1_REF, 3, 2, 1, entryOf(metricKey, newMeasureBuilder().create(16))); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_2_REF, 7, 1, 1, entryOf(metricKey, newMeasureBuilder().create(3))); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_3_REF, NO_METRIC, NO_METRIC, NO_METRIC); | |||
verifyMeasuresOnOtherComponent(SUB_MODULE_REF, 10, 3, 2, entryOf(metricKey, newMeasureBuilder().create(19))); | |||
verifyMeasuresOnOtherComponent(MODULE_REF, 10, 3, 2, entryOf(metricKey, newMeasureBuilder().create(19))); | |||
verifyMeasuresOnOtherComponent(ROOT_REF, 10, 3, 2, entryOf(metricKey, newMeasureBuilder().create(19))); | |||
} | |||
private void verifyTwoMeasureAggregation(String metric1Key, String metric2Key) { | |||
@@ -142,48 +167,23 @@ public class ReportSizeMeasuresStepTest { | |||
underTest.execute(); | |||
verifyMeasuresOnFile(FILE_1_REF, 1); | |||
verifyMeasuresOnFile(FILE_2_REF, 1); | |||
verifyMeasuresOnFile(FILE_3_REF, 1); | |||
verifyMeasuresOnFile(FILE_1_REF, 1, 1); | |||
verifyMeasuresOnFile(FILE_2_REF, 2, 1); | |||
verifyMeasuresOnFile(FILE_3_REF, 7, 1); | |||
verifyNoMeasure(UNIT_TEST_1_REF); | |||
verifyNoMeasure(UNIT_TEST_2_REF); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_1_REF, 2, 1, | |||
verifyMeasuresOnOtherComponent(DIRECTORY_1_REF, 3, 2, 1, | |||
entryOf(metric1Key, newMeasureBuilder().create(7)), entryOf(metric2Key, newMeasureBuilder().create(10))); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_2_REF, 1, 1, | |||
verifyMeasuresOnOtherComponent(DIRECTORY_2_REF, 7, 1, 1, | |||
entryOf(metric2Key, newMeasureBuilder().create(90))); | |||
MeasureRepoEntry[] subModuleAndAboveEntries = { | |||
entryOf(metric1Key, newMeasureBuilder().create(7)), | |||
entryOf(metric2Key, newMeasureBuilder().create(100)) | |||
}; | |||
verifyMeasuresOnOtherComponent(DIRECTORY_3_REF, NO_METRIC, NO_METRIC); | |||
verifyMeasuresOnOtherComponent(SUB_MODULE_REF, 3, 2, subModuleAndAboveEntries); | |||
verifyMeasuresOnOtherComponent(MODULE_REF, 3, 2, subModuleAndAboveEntries); | |||
verifyMeasuresOnOtherComponent(ROOT_REF, 3, 2, subModuleAndAboveEntries); | |||
} | |||
@Test | |||
public void verify_NCLOC_measure_aggregation() { | |||
verifyMetricAggregation(NCLOC_KEY); | |||
} | |||
private void verifyMetricAggregation(String metricKey) { | |||
measureRepository.addRawMeasure(FILE_1_REF, metricKey, newMeasureBuilder().create(10)); | |||
measureRepository.addRawMeasure(FILE_2_REF, metricKey, newMeasureBuilder().create(6)); | |||
measureRepository.addRawMeasure(UNIT_TEST_1_REF, metricKey, newMeasureBuilder().create(3)); | |||
underTest.execute(); | |||
verifyMeasuresOnFile(FILE_1_REF, 1); | |||
verifyMeasuresOnFile(FILE_2_REF, 1); | |||
verifyMeasuresOnFile(FILE_3_REF, 1); | |||
verifyNoMeasure(UNIT_TEST_1_REF); | |||
verifyNoMeasure(UNIT_TEST_2_REF); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_1_REF, 2, 1, entryOf(metricKey, newMeasureBuilder().create(16))); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_2_REF, 1, 1, entryOf(metricKey, newMeasureBuilder().create(3))); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_3_REF, NO_METRIC, NO_METRIC); | |||
verifyMeasuresOnOtherComponent(SUB_MODULE_REF, 3, 2, entryOf(metricKey, newMeasureBuilder().create(19))); | |||
verifyMeasuresOnOtherComponent(MODULE_REF, 3, 2, entryOf(metricKey, newMeasureBuilder().create(19))); | |||
verifyMeasuresOnOtherComponent(ROOT_REF, 3, 2, entryOf(metricKey, newMeasureBuilder().create(19))); | |||
verifyMeasuresOnOtherComponent(DIRECTORY_3_REF, NO_METRIC, NO_METRIC, NO_METRIC); | |||
verifyMeasuresOnOtherComponent(SUB_MODULE_REF, 10, 3, 2, subModuleAndAboveEntries); | |||
verifyMeasuresOnOtherComponent(MODULE_REF, 10, 3, 2, subModuleAndAboveEntries); | |||
verifyMeasuresOnOtherComponent(ROOT_REF, 10, 3, 2, subModuleAndAboveEntries); | |||
} | |||
@Test | |||
@@ -196,14 +196,18 @@ public class ReportSizeMeasuresStepTest { | |||
verifyMetricAggregation(CLASSES_KEY); | |||
} | |||
private void verifyMeasuresOnFile(int componentRef, int fileCount) { | |||
private void verifyMeasuresOnFile(int componentRef, int linesCount, int fileCount) { | |||
assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))) | |||
.containsOnly(entryOf(FILES_KEY, newMeasureBuilder().create(fileCount))); | |||
.containsOnly( | |||
entryOf(LINES_KEY, newMeasureBuilder().create(linesCount)), | |||
entryOf(FILES_KEY, newMeasureBuilder().create(fileCount)) | |||
); | |||
} | |||
private void verifyMeasuresOnOtherComponent(int componentRef, @Nullable Integer fileCount, @Nullable Integer directoryCount, MeasureRepoEntry... otherMeasures) { | |||
private void verifyMeasuresOnOtherComponent(int componentRef, @Nullable Integer linesCount, @Nullable Integer fileCount, @Nullable Integer directoryCount, MeasureRepoEntry... otherMeasures) { | |||
MeasureRepoEntry[] measureRepoEntries = concatIntoArray( | |||
otherMeasures, | |||
linesCount == null ? null : entryOf(LINES_KEY, newMeasureBuilder().create(linesCount)), | |||
fileCount == null ? null : entryOf(FILES_KEY, newMeasureBuilder().create(fileCount)), | |||
directoryCount == null ? null : entryOf(DIRECTORIES_KEY, newMeasureBuilder().create(directoryCount)) | |||
); |
@@ -22,7 +22,6 @@ package org.sonar.server.computation.task.projectanalysis.step; | |||
import javax.annotation.Nullable; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; | |||
import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry; | |||
import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule; | |||
@@ -33,13 +32,23 @@ import static com.google.common.collect.FluentIterable.from; | |||
import static com.google.common.collect.Iterables.concat; | |||
import static java.util.Arrays.asList; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.api.measures.CoreMetrics.ACCESSORS; | |||
import static org.sonar.api.measures.CoreMetrics.CLASSES; | |||
import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.DIRECTORIES; | |||
import static org.sonar.api.measures.CoreMetrics.DIRECTORIES_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.FILES; | |||
import static org.sonar.api.measures.CoreMetrics.FILES_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.FUNCTIONS; | |||
import static org.sonar.api.measures.CoreMetrics.FUNCTIONS_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.GENERATED_LINES; | |||
import static org.sonar.api.measures.CoreMetrics.GENERATED_LINES_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.GENERATED_NCLOC; | |||
import static org.sonar.api.measures.CoreMetrics.LINES; | |||
import static org.sonar.api.measures.CoreMetrics.LINES_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.NCLOC; | |||
import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY; | |||
import static org.sonar.api.measures.CoreMetrics.STATEMENTS; | |||
import static org.sonar.api.measures.CoreMetrics.STATEMENTS_KEY; | |||
import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT_VIEW; | |||
import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.SUBVIEW; | |||
@@ -88,28 +97,34 @@ public class ViewsSizeMeasuresStepTest { | |||
.build()); | |||
@Rule | |||
public MetricRepositoryRule metricRepository = new MetricRepositoryRule() | |||
.add(CoreMetrics.FILES) | |||
.add(CoreMetrics.DIRECTORIES) | |||
.add(CoreMetrics.LINES) | |||
.add(CoreMetrics.GENERATED_LINES) | |||
.add(CoreMetrics.NCLOC) | |||
.add(CoreMetrics.GENERATED_NCLOC) | |||
.add(CoreMetrics.FUNCTIONS) | |||
.add(CoreMetrics.STATEMENTS) | |||
.add(CoreMetrics.CLASSES) | |||
.add(CoreMetrics.ACCESSORS); | |||
.add(FILES) | |||
.add(DIRECTORIES) | |||
.add(LINES) | |||
.add(GENERATED_LINES) | |||
.add(NCLOC) | |||
.add(GENERATED_NCLOC) | |||
.add(FUNCTIONS) | |||
.add(STATEMENTS) | |||
.add(CLASSES) | |||
.add(ACCESSORS); | |||
@Rule | |||
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository) | |||
.addRawMeasure(PROJECTVIEW_1_REF, CoreMetrics.FILES_KEY, newMeasureBuilder().create(1)) | |||
.addRawMeasure(PROJECTVIEW_2_REF, CoreMetrics.FILES_KEY, newMeasureBuilder().create(2)) | |||
.addRawMeasure(PROJECTVIEW_3_REF, CoreMetrics.FILES_KEY, newMeasureBuilder().create(3)) | |||
.addRawMeasure(PROJECTVIEW_1_REF, LINES_KEY, newMeasureBuilder().create(1)) | |||
.addRawMeasure(PROJECTVIEW_2_REF, LINES_KEY, newMeasureBuilder().create(2)) | |||
.addRawMeasure(PROJECTVIEW_3_REF, LINES_KEY, newMeasureBuilder().create(5)) | |||
// PROJECTVIEW_4_REF has no lines metric | |||
.addRawMeasure(PROJECTVIEW_5_REF, LINES_KEY, newMeasureBuilder().create(5)) | |||
.addRawMeasure(PROJECTVIEW_1_REF, FILES_KEY, newMeasureBuilder().create(1)) | |||
.addRawMeasure(PROJECTVIEW_2_REF, FILES_KEY, newMeasureBuilder().create(2)) | |||
.addRawMeasure(PROJECTVIEW_3_REF, FILES_KEY, newMeasureBuilder().create(3)) | |||
// PROJECTVIEW_4_REF has no file metric | |||
.addRawMeasure(PROJECTVIEW_5_REF, CoreMetrics.FILES_KEY, newMeasureBuilder().create(5)) | |||
.addRawMeasure(PROJECTVIEW_1_REF, CoreMetrics.DIRECTORIES_KEY, newMeasureBuilder().create(1)) | |||
.addRawMeasure(PROJECTVIEW_2_REF, CoreMetrics.DIRECTORIES_KEY, newMeasureBuilder().create(2)) | |||
.addRawMeasure(PROJECTVIEW_5_REF, FILES_KEY, newMeasureBuilder().create(5)) | |||
.addRawMeasure(PROJECTVIEW_1_REF, DIRECTORIES_KEY, newMeasureBuilder().create(1)) | |||
.addRawMeasure(PROJECTVIEW_2_REF, DIRECTORIES_KEY, newMeasureBuilder().create(2)) | |||
// PROJECTVIEW_3_REF has no directory metric | |||
.addRawMeasure(PROJECTVIEW_4_REF, CoreMetrics.DIRECTORIES_KEY, newMeasureBuilder().create(4)) | |||
.addRawMeasure(PROJECTVIEW_5_REF, CoreMetrics.DIRECTORIES_KEY, newMeasureBuilder().create(5)); | |||
.addRawMeasure(PROJECTVIEW_4_REF, DIRECTORIES_KEY, newMeasureBuilder().create(4)) | |||
.addRawMeasure(PROJECTVIEW_5_REF, DIRECTORIES_KEY, newMeasureBuilder().create(5)); | |||
private SizeMeasuresStep underTest = new SizeMeasuresStep(treeRootHolder, metricRepository, measureRepository); | |||
@@ -122,17 +137,43 @@ public class ViewsSizeMeasuresStepTest { | |||
verifyNoMeasure(PROJECTVIEW_3_REF); | |||
verifyNoMeasure(PROJECTVIEW_4_REF); | |||
verifyNoMeasure(PROJECTVIEW_5_REF); | |||
verifyMeasures(SUB_SUBVIEW_1_REF, 3, 3); | |||
verifyMeasures(SUB_SUBVIEW_2_REF, 3, 0); | |||
verifyMeasures(SUB_SUBVIEW_3_REF, NO_METRIC, NO_METRIC); | |||
verifyMeasures(SUBVIEW_1_REF, 6, 7); | |||
verifyMeasures(SUBVIEW_2_REF, NO_METRIC, NO_METRIC); | |||
verifyMeasures(ROOT_REF, 11, 12); | |||
verifyMeasures(SUB_SUBVIEW_1_REF, 3, 3, 3); | |||
verifyMeasures(SUB_SUBVIEW_2_REF, 5, 3, 0); | |||
verifyMeasures(SUB_SUBVIEW_3_REF, NO_METRIC, NO_METRIC, NO_METRIC); | |||
verifyMeasures(SUBVIEW_1_REF, 8, 6, 7); | |||
verifyMeasures(SUBVIEW_2_REF, NO_METRIC, NO_METRIC, NO_METRIC); | |||
verifyMeasures(ROOT_REF, 13, 11, 12); | |||
} | |||
@Test | |||
public void verify_LINE_related_measures_aggregation() { | |||
verifyTwoMeasureAggregation(LINES_KEY, GENERATED_LINES_KEY); | |||
public void verify_GENERATED_LINES_related_measures_aggregation() { | |||
verifyMetricAggregation(GENERATED_LINES_KEY); | |||
} | |||
@Test | |||
public void verify_NCLOC_measure_aggregation() { | |||
verifyMetricAggregation(NCLOC_KEY); | |||
} | |||
private void verifyMetricAggregation(String metricKey) { | |||
measureRepository.addRawMeasure(PROJECTVIEW_1_REF, metricKey, newMeasureBuilder().create(10)); | |||
measureRepository.addRawMeasure(PROJECTVIEW_2_REF, metricKey, newMeasureBuilder().create(6)); | |||
measureRepository.addRawMeasure(PROJECTVIEW_4_REF, metricKey, newMeasureBuilder().create(3)); | |||
measureRepository.addRawMeasure(PROJECTVIEW_5_REF, metricKey, newMeasureBuilder().create(7)); | |||
underTest.execute(); | |||
verifyNoMeasure(PROJECTVIEW_1_REF); | |||
verifyNoMeasure(PROJECTVIEW_2_REF); | |||
verifyNoMeasure(PROJECTVIEW_3_REF); | |||
verifyNoMeasure(PROJECTVIEW_4_REF); | |||
verifyNoMeasure(PROJECTVIEW_5_REF); | |||
verifyMeasures(SUB_SUBVIEW_1_REF, 3, 3, 3, entryOf(metricKey, newMeasureBuilder().create(16))); | |||
verifyMeasures(SUB_SUBVIEW_2_REF, 5, 3, 0); | |||
verifyMeasures(SUB_SUBVIEW_3_REF, NO_METRIC, NO_METRIC, NO_METRIC, entryOf(metricKey, newMeasureBuilder().create(3))); | |||
verifyMeasures(SUBVIEW_1_REF, 8, 6, 7, entryOf(metricKey, newMeasureBuilder().create(19))); | |||
verifyMeasures(SUBVIEW_2_REF, NO_METRIC, NO_METRIC, NO_METRIC); | |||
verifyMeasures(ROOT_REF, 13, 11, 12, entryOf(metricKey, newMeasureBuilder().create(26))); | |||
} | |||
private void verifyTwoMeasureAggregation(String metric1Key, String metric2Key) { | |||
@@ -154,42 +195,16 @@ public class ViewsSizeMeasuresStepTest { | |||
verifyNoMeasure(PROJECTVIEW_4_REF); | |||
verifyNoMeasure(PROJECTVIEW_5_REF); | |||
verifyNoMeasure(PROJECTVIEW_4_REF); | |||
verifyMeasures(SUB_SUBVIEW_1_REF, 3, 3, | |||
entryOf(metric1Key, newMeasureBuilder().create(7)), entryOf(metric2Key, newMeasureBuilder().create(10))); | |||
verifyMeasures(SUB_SUBVIEW_2_REF, 3, 0); | |||
verifyMeasures(SUB_SUBVIEW_3_REF, NO_METRIC, NO_METRIC, | |||
entryOf(metric2Key, newMeasureBuilder().create(90))); | |||
verifyMeasures(SUBVIEW_1_REF, 6, 7, | |||
entryOf(metric1Key, newMeasureBuilder().create(7)), entryOf(metric2Key, newMeasureBuilder().create(100))); | |||
verifyMeasures(SUBVIEW_2_REF, NO_METRIC, NO_METRIC); | |||
verifyMeasures(ROOT_REF, 11, 12, | |||
entryOf(metric1Key, newMeasureBuilder().create(10)), entryOf(metric2Key, newMeasureBuilder().create(107))); | |||
} | |||
@Test | |||
public void verify_NCLOC_measure_aggregation() { | |||
verifyMetricAggregation(NCLOC_KEY); | |||
} | |||
private void verifyMetricAggregation(String metricKey) { | |||
measureRepository.addRawMeasure(PROJECTVIEW_1_REF, metricKey, newMeasureBuilder().create(10)); | |||
measureRepository.addRawMeasure(PROJECTVIEW_2_REF, metricKey, newMeasureBuilder().create(6)); | |||
measureRepository.addRawMeasure(PROJECTVIEW_4_REF, metricKey, newMeasureBuilder().create(3)); | |||
measureRepository.addRawMeasure(PROJECTVIEW_5_REF, metricKey, newMeasureBuilder().create(7)); | |||
underTest.execute(); | |||
verifyNoMeasure(PROJECTVIEW_1_REF); | |||
verifyNoMeasure(PROJECTVIEW_2_REF); | |||
verifyNoMeasure(PROJECTVIEW_3_REF); | |||
verifyNoMeasure(PROJECTVIEW_4_REF); | |||
verifyNoMeasure(PROJECTVIEW_5_REF); | |||
verifyMeasures(SUB_SUBVIEW_1_REF, 3, 3, entryOf(metricKey, newMeasureBuilder().create(16))); | |||
verifyMeasures(SUB_SUBVIEW_2_REF, 3, 0); | |||
verifyMeasures(SUB_SUBVIEW_3_REF, NO_METRIC, NO_METRIC, entryOf(metricKey, newMeasureBuilder().create(3))); | |||
verifyMeasures(SUBVIEW_1_REF, 6, 7, entryOf(metricKey, newMeasureBuilder().create(19))); | |||
verifyMeasures(SUBVIEW_2_REF, NO_METRIC, NO_METRIC); | |||
verifyMeasures(ROOT_REF, 11, 12, entryOf(metricKey, newMeasureBuilder().create(26))); | |||
verifyMeasures(SUB_SUBVIEW_1_REF, 3, 3, 3, | |||
entryOf(metric1Key, newMeasureBuilder().create(7)), entryOf(metric2Key, newMeasureBuilder().create(10))); | |||
verifyMeasures(SUB_SUBVIEW_2_REF, 5, 3, 0); | |||
verifyMeasures(SUB_SUBVIEW_3_REF, NO_METRIC, NO_METRIC, NO_METRIC, | |||
entryOf(metric2Key, newMeasureBuilder().create(90))); | |||
verifyMeasures(SUBVIEW_1_REF, 8, 6, 7, | |||
entryOf(metric1Key, newMeasureBuilder().create(7)), entryOf(metric2Key, newMeasureBuilder().create(100))); | |||
verifyMeasures(SUBVIEW_2_REF, NO_METRIC, NO_METRIC, NO_METRIC); | |||
verifyMeasures(ROOT_REF, 13, 11, 12, | |||
entryOf(metric1Key, newMeasureBuilder().create(10)), entryOf(metric2Key, newMeasureBuilder().create(107))); | |||
} | |||
@Test | |||
@@ -202,14 +217,15 @@ public class ViewsSizeMeasuresStepTest { | |||
verifyMetricAggregation(CLASSES_KEY); | |||
} | |||
private void verifyMeasures(int componentRef, @Nullable Integer fileCount, @Nullable Integer directoryCount, MeasureRepoEntry... otherMeasures) { | |||
private void verifyMeasures(int componentRef, @Nullable Integer linesCount, @Nullable Integer fileCount, @Nullable Integer directoryCount, MeasureRepoEntry... otherMeasures) { | |||
assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))) | |||
.containsOnly( | |||
concatIntoArray(otherMeasures, createFileAndDirectoryEntries(fileCount, directoryCount))); | |||
.containsOnly( | |||
concatIntoArray(otherMeasures, createFileAndDirectoryEntries(linesCount, fileCount, directoryCount))); | |||
} | |||
private static MeasureRepoEntry[] createFileAndDirectoryEntries(@Nullable Integer fileCount, @Nullable Integer directoryCount) { | |||
private static MeasureRepoEntry[] createFileAndDirectoryEntries(@Nullable Integer linesCount, @Nullable Integer fileCount, @Nullable Integer directoryCount) { | |||
return new MeasureRepoEntry[] { | |||
linesCount == null ? null : entryOf(LINES_KEY, newMeasureBuilder().create(linesCount)), | |||
fileCount == null ? null : entryOf(FILES_KEY, newMeasureBuilder().create(fileCount)), | |||
directoryCount == null ? null : entryOf(DIRECTORIES_KEY, newMeasureBuilder().create(directoryCount)) | |||
}; |
@@ -20,11 +20,10 @@ | |||
package org.sonar.core.metric; | |||
import com.google.common.collect.ImmutableSet; | |||
import com.google.common.collect.Iterables; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
import java.util.Set; | |||
import java.util.stream.Collectors; | |||
import java.util.stream.Stream; | |||
import org.sonar.api.batch.ScannerSide; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.measures.Metric; | |||
@@ -49,7 +48,6 @@ import static org.sonar.api.measures.CoreMetrics.FUNCTIONS; | |||
import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION; | |||
import static org.sonar.api.measures.CoreMetrics.GENERATED_LINES; | |||
import static org.sonar.api.measures.CoreMetrics.GENERATED_NCLOC; | |||
import static org.sonar.api.measures.CoreMetrics.LINES; | |||
import static org.sonar.api.measures.CoreMetrics.LINES_TO_COVER; | |||
import static org.sonar.api.measures.CoreMetrics.NCLOC; | |||
import static org.sonar.api.measures.CoreMetrics.NCLOC_DATA; | |||
@@ -64,6 +62,7 @@ import static org.sonar.api.measures.CoreMetrics.TEST_EXECUTION_TIME; | |||
import static org.sonar.api.measures.CoreMetrics.TEST_FAILURES; | |||
import static org.sonar.api.measures.CoreMetrics.UNCOVERED_CONDITIONS; | |||
import static org.sonar.api.measures.CoreMetrics.UNCOVERED_LINES; | |||
import static org.sonar.core.util.stream.Collectors.toSet; | |||
/** | |||
* This class is used to know the list of metrics that can be sent in the analysis report. | |||
@@ -74,8 +73,7 @@ import static org.sonar.api.measures.CoreMetrics.UNCOVERED_LINES; | |||
@ScannerSide | |||
public class ScannerMetrics { | |||
private static final Set<Metric> ALLOWED_CORE_METRICS = ImmutableSet.<Metric>of( | |||
LINES, | |||
private static final Set<Metric> ALLOWED_CORE_METRICS = ImmutableSet.of( | |||
GENERATED_LINES, | |||
NCLOC, | |||
NCLOC_DATA, | |||
@@ -123,17 +121,16 @@ public class ScannerMetrics { | |||
} | |||
public ScannerMetrics(Metrics[] metricsRepositories) { | |||
this.metrics = ImmutableSet.copyOf(Iterables.concat(getPluginMetrics(metricsRepositories), ALLOWED_CORE_METRICS)); | |||
this.metrics = Stream.concat(getPluginMetrics(metricsRepositories), ALLOWED_CORE_METRICS.stream()).collect(toSet()); | |||
} | |||
public Set<Metric> getMetrics() { | |||
return metrics; | |||
} | |||
private static Iterable<Metric> getPluginMetrics(Metrics[] metricsRepositories) { | |||
private static Stream<Metric> getPluginMetrics(Metrics[] metricsRepositories) { | |||
return Arrays.stream(metricsRepositories) | |||
.map(Metrics::getMetrics) | |||
.flatMap(List::stream) | |||
.collect(Collectors.toList()); | |||
.flatMap(List::stream); | |||
} | |||
} |
@@ -36,7 +36,7 @@ public class ScannerMetricsTest { | |||
@Test | |||
public void check_number_of_allowed_core_metrics() throws Exception { | |||
assertThat(SENSOR_METRICS_WITHOUT_METRIC_PLUGIN.getMetrics()).hasSize(34); | |||
assertThat(SENSOR_METRICS_WITHOUT_METRIC_PLUGIN.getMetrics()).hasSize(33); | |||
} | |||
@Test |