aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2015-07-21 17:24:15 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2015-07-23 11:06:03 +0200
commitc5a1decadac5bcefe65fc1194c1694e2b6c73143 (patch)
tree7e555bd87562b19e1ec86ad30924748554755d36 /server
parenta774449c9a95139486a69a5a02ece6206ea15c95 (diff)
downloadsonarqube-c5a1decadac5bcefe65fc1194c1694e2b6c73143.tar.gz
sonarqube-c5a1decadac5bcefe65fc1194c1694e2b6c73143.zip
SONAR-6676 compute FILES and DIRECTORIES measures in CE
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/FileAndDirectoryMeasuresStep.java123
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/FileAndDirectoryMeasuresStepTest.java111
3 files changed, 235 insertions, 0 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java
index c38bc358f96..fe213aaabe6 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java
@@ -52,6 +52,7 @@ public class ComputationSteps {
FeedPeriodsStep.class,
// data computation
+ FileAndDirectoryMeasuresStep.class,
NewCoverageMeasuresStep.class,
CoverageMeasuresStep.class,
CommentMeasuresStep.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/FileAndDirectoryMeasuresStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/FileAndDirectoryMeasuresStep.java
new file mode 100644
index 00000000000..563bc3e5495
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/FileAndDirectoryMeasuresStep.java
@@ -0,0 +1,123 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.step;
+
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.PathAwareVisitor;
+import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.computation.measure.MeasureRepository;
+import org.sonar.server.computation.metric.Metric;
+import org.sonar.server.computation.metric.MetricRepository;
+
+import static org.sonar.server.computation.component.Component.Type.FILE;
+import static org.sonar.server.computation.component.ComponentVisitor.Order.POST_ORDER;
+import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
+
+public class FileAndDirectoryMeasuresStep implements ComputationStep {
+ private static final CounterStackElementFactory COUNTER_STACK_ELEMENT_FACTORY = new CounterStackElementFactory();
+
+ private final TreeRootHolder treeRootHolder;
+ private final MetricRepository metricRepository;
+ private final MeasureRepository measureRepository;
+
+ public FileAndDirectoryMeasuresStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository) {
+ this.treeRootHolder = treeRootHolder;
+ this.metricRepository = metricRepository;
+ this.measureRepository = measureRepository;
+ }
+
+ @Override
+ public void execute() {
+ Metric fileMetric = metricRepository.getByKey(CoreMetrics.FILES_KEY);
+ Metric directoryMetric = metricRepository.getByKey(CoreMetrics.DIRECTORIES_KEY);
+
+ new FileAndDirectoryMeasureVisitor(directoryMetric, fileMetric).visit(treeRootHolder.getRoot());
+ }
+
+ @Override
+ public String getDescription() {
+ return "File and Directory measures";
+ }
+
+ private class FileAndDirectoryMeasureVisitor extends PathAwareVisitor<Counter> {
+ private final Metric directoryMetric;
+ private final Metric fileMetric;
+
+ public FileAndDirectoryMeasureVisitor(Metric directoryMetric, Metric fileMetric) {
+ super(FILE, POST_ORDER, COUNTER_STACK_ELEMENT_FACTORY);
+ this.directoryMetric = directoryMetric;
+ this.fileMetric = fileMetric;
+ }
+
+ @Override
+ protected void visitProject(Component project, Path<Counter> path) {
+ measureRepository.add(project, directoryMetric, newMeasureBuilder().create(path.current().directories));
+ measureRepository.add(project, fileMetric, newMeasureBuilder().create(path.current().files));
+ }
+
+ @Override
+ protected void visitModule(Component module, Path<Counter> path) {
+ measureRepository.add(module, directoryMetric, newMeasureBuilder().create(path.current().directories));
+ measureRepository.add(module, fileMetric, newMeasureBuilder().create(path.current().files));
+
+ path.parent().directories += path.current().directories;
+ path.parent().files += path.current().files;
+ }
+
+ @Override
+ protected void visitDirectory(Component directory, Path<Counter> path) {
+ measureRepository.add(directory, directoryMetric, newMeasureBuilder().create(1));
+ measureRepository.add(directory, fileMetric, newMeasureBuilder().create(path.current().files));
+
+ path.parent().directories += 1;
+ path.parent().files += path.current().files;
+ }
+
+ @Override
+ protected void visitFile(Component file, Path<Counter> path) {
+ if (file.getFileAttributes().isUnitTest()) {
+ return;
+ }
+ measureRepository.add(file, fileMetric, newMeasureBuilder().create(1));
+
+ path.parent().files += 1;
+ }
+
+ }
+
+ private static class Counter {
+ private int files = 0;
+ private int directories = 0;
+
+ }
+
+ private static class CounterStackElementFactory extends PathAwareVisitor.SimpleStackElementFactory<Counter> {
+ @Override
+ public Counter createForAny(Component component) {
+ return new Counter();
+ }
+
+ @Override
+ public Counter createForFile(Component file) {
+ return null;
+ }
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/FileAndDirectoryMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/FileAndDirectoryMeasuresStepTest.java
new file mode 100644
index 00000000000..3989a86268a
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/FileAndDirectoryMeasuresStepTest.java
@@ -0,0 +1,111 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.step;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.FileAttributes;
+import org.sonar.server.computation.measure.MeasureRepositoryRule;
+import org.sonar.server.computation.metric.MetricRepositoryRule;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.measures.CoreMetrics.DIRECTORIES_KEY;
+import static org.sonar.api.measures.CoreMetrics.FILES_KEY;
+import static org.sonar.server.computation.component.Component.Type.DIRECTORY;
+import static org.sonar.server.computation.component.Component.Type.FILE;
+import static org.sonar.server.computation.component.Component.Type.MODULE;
+import static org.sonar.server.computation.component.Component.Type.PROJECT;
+import static org.sonar.server.computation.component.DumbComponent.builder;
+import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
+import static org.sonar.server.computation.measure.MeasureRepoEntry.entryOf;
+import static org.sonar.server.computation.measure.MeasureRepoEntry.toEntries;
+
+public class FileAndDirectoryMeasuresStepTest {
+
+ private static final int ROOT_REF = 1;
+ private static final int MODULE_REF = 12;
+ private static final int SUB_MODULE_REF = 123;
+ private static final int DIRECTORY_1_REF = 1234;
+ private static final int DIRECTORY_2_REF = 1235;
+ private static final int FILE_1_REF = 12341;
+ private static final int FILE_2_REF = 12343;
+ private static final int FILE_3_REF = 12351;
+ private static final int UNIT_TEST_REF = 12352;
+ public static final String LANGUAGE_KEY_DOES_NOT_MATTER_HERE = null;
+
+ @Rule
+ public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+ @Rule
+ public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
+ .add(CoreMetrics.FILES)
+ .add(CoreMetrics.DIRECTORIES);
+ @Rule
+ public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
+
+ private FileAndDirectoryMeasuresStep underTest = new FileAndDirectoryMeasuresStep(treeRootHolder, metricRepository, measureRepository);
+
+ @Test
+ public void verify_FILE_and_DIRECTORY_computation_and_aggregation() {
+ treeRootHolder.setRoot(
+ builder(PROJECT, ROOT_REF)
+ .addChildren(
+ builder(MODULE, MODULE_REF)
+ .addChildren(
+ builder(MODULE, SUB_MODULE_REF)
+ .addChildren(
+ builder(DIRECTORY, DIRECTORY_1_REF)
+ .addChildren(
+ builder(FILE, FILE_1_REF).build(),
+ builder(FILE, FILE_2_REF).build())
+ .build(),
+ builder(DIRECTORY, DIRECTORY_2_REF)
+ .addChildren(
+ builder(FILE, FILE_3_REF).build(),
+ builder(FILE, UNIT_TEST_REF).setFileAttributes(new FileAttributes(true, LANGUAGE_KEY_DOES_NOT_MATTER_HERE)).build())
+ .build())
+ .build())
+ .build())
+ .build());
+
+ underTest.execute();
+
+ verifyMeasuresOnFile(FILE_1_REF, 1);
+ verifyMeasuresOnFile(FILE_2_REF, 1);
+ verifyMeasuresOnFile(FILE_3_REF, 1);
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(UNIT_TEST_REF))).isEmpty();
+ verifyMeasuresOnOtherComponent(DIRECTORY_1_REF, 2, 1);
+ verifyMeasuresOnOtherComponent(DIRECTORY_2_REF, 1, 1);
+ verifyMeasuresOnOtherComponent(SUB_MODULE_REF, 3, 2);
+ verifyMeasuresOnOtherComponent(MODULE_REF, 3, 2);
+ verifyMeasuresOnOtherComponent(ROOT_REF, 3, 2);
+ }
+
+ private void verifyMeasuresOnFile(int componentRef, int fileCount) {
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef)))
+ .containsOnly(entryOf(FILES_KEY, newMeasureBuilder().create(fileCount)));
+ }
+
+ private void verifyMeasuresOnOtherComponent(int componentRef, int fileCount, int directoryCount) {
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef)))
+ .containsOnly(entryOf(FILES_KEY, newMeasureBuilder().create(fileCount)), entryOf(DIRECTORIES_KEY, newMeasureBuilder().create(directoryCount)));
+ }
+}