From 32b2fe0570c8f7adba76850f6d44ab230b8b13f5 Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Tue, 22 Nov 2016 13:36:51 +0100 Subject: SONAR-8418 Stop computing ratings for views Ratings for views should be computed in Governance --- .../MaintainabilityMeasuresVisitor.java | 36 +- ...eliabilityAndSecurityRatingMeasuresVisitor.java | 36 +- ...aintainabilityMeasuresVisitorForReportTest.java | 368 --------------------- ...MaintainabilityMeasuresVisitorForViewsTest.java | 235 ------------- .../MaintainabilityMeasuresVisitorTest.java | 368 +++++++++++++++++++++ ...SecurityRatingMeasuresVisitorForReportTest.java | 264 --------------- ...dSecurityRatingMeasuresVisitorForViewsTest.java | 155 --------- ...bilityAndSecurityRatingMeasuresVisitorTest.java | 264 +++++++++++++++ 8 files changed, 637 insertions(+), 1089 deletions(-) delete mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorForReportTest.java delete mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorForViewsTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java delete mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForReportTest.java delete mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForViewsTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java index 8859f889450..80a340eb1d3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java @@ -21,8 +21,6 @@ package org.sonar.server.computation.task.projectanalysis.qualitymodel; import com.google.common.base.Optional; import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; 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.PathAwareVisitorAdapter; @@ -43,15 +41,13 @@ import static org.sonar.server.computation.task.projectanalysis.component.Compon import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; /** - * Compute measures related to maintainability : + * Compute measures related to maintainability for projects and descendants : * {@link CoreMetrics#DEVELOPMENT_COST_KEY} * {@link CoreMetrics#SQALE_DEBT_RATIO_KEY} * {@link CoreMetrics#SQALE_RATING_KEY} * {@link CoreMetrics#EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY} */ public class MaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter { - private static final Logger LOG = Loggers.get(MaintainabilityMeasuresVisitor.class); - private final MeasureRepository measureRepository; private final RatingSettings ratingSettings; private final RatingGrid ratingGrid; @@ -65,7 +61,7 @@ public class MaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter
path) { - computeAndSaveMeasures(view, path); - } - - @Override - public void visitSubView(Component subView, Path path) { - computeAndSaveMeasures(subView, path); - } - - @Override - public void visitProjectView(Component projectView, Path path) { - Optional developmentCostMeasure = measureRepository.getRawMeasure(projectView, developmentCostMetric); - if (developmentCostMeasure.isPresent()) { - try { - path.parent().addDevCosts(Long.valueOf(developmentCostMeasure.get().getStringValue())); - } catch (NumberFormatException e) { - LOG.trace("Failed to parse value of metric {} for component {}", developmentCostMetric.getName(), projectView.getKey()); - } - } - } - private void computeAndSaveMeasures(Component component, Path path) { addDevelopmentCostMeasure(component, path.current()); @@ -210,11 +184,5 @@ public class MaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter
metricsByKey; public ReliabilityAndSecurityRatingMeasuresVisitor(MetricRepository metricRepository, MeasureRepository measureRepository, ComponentIssuesRepository componentIssuesRepository) { - super(LEAVES, POST_ORDER, CounterFactory.INSTANCE); + super(FILE, POST_ORDER, CounterFactory.INSTANCE); this.measureRepository = measureRepository; this.componentIssuesRepository = componentIssuesRepository; @@ -111,26 +109,6 @@ public class ReliabilityAndSecurityRatingMeasuresVisitor extends PathAwareVisito computeAndSaveMeasures(file, path); } - @Override - public void visitView(Component view, Path path) { - computeAndSaveMeasures(view, path); - } - - @Override - public void visitSubView(Component subView, Path path) { - computeAndSaveMeasures(subView, path); - } - - @Override - public void visitProjectView(Component projectView, Path path) { - path.parent().ratingValueByMetric.entrySet().forEach(entry -> { - Optional ratingMeasure = measureRepository.getRawMeasure(projectView, metricsByKey.get(entry.getKey())); - if (ratingMeasure.isPresent()) { - entry.getValue().increment(valueOf(ratingMeasure.get().getData())); - } - }); - } - private void computeAndSaveMeasures(Component component, Path path) { processIssues(component, path); path.current().ratingValueByMetric.entrySet().forEach( @@ -190,13 +168,5 @@ public class ReliabilityAndSecurityRatingMeasuresVisitor extends PathAwareVisito public Counter createForAny(Component component) { return new Counter(); } - - /** - * Counter is not used at ProjectView level, saves on instantiating useless objects - */ - @Override - public Counter createForProjectView(Component projectView) { - return null; - } } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorForReportTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorForReportTest.java deleted file mode 100644 index 4dd13473124..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorForReportTest.java +++ /dev/null @@ -1,368 +0,0 @@ -/* - * 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.qualitymodel; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.server.computation.task.projectanalysis.component.Component; -import org.sonar.server.computation.task.projectanalysis.component.FileAttributes; -import org.sonar.server.computation.task.projectanalysis.component.ReportComponent; -import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; -import org.sonar.server.computation.task.projectanalysis.component.VisitorsCrawler; -import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.measure.Measure; -import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.api.measures.CoreMetrics.DEVELOPMENT_COST; -import static org.sonar.api.measures.CoreMetrics.DEVELOPMENT_COST_KEY; -import static org.sonar.api.measures.CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A; -import static org.sonar.api.measures.CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_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.SQALE_DEBT_RATIO; -import static org.sonar.api.measures.CoreMetrics.SQALE_DEBT_RATIO_KEY; -import static org.sonar.api.measures.CoreMetrics.SQALE_RATING; -import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY; -import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT; -import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY; -import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.DIRECTORY; -import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE; -import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.MODULE; -import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT; -import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder; -import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; -import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.entryOf; -import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.E; - -public class MaintainabilityMeasuresVisitorForReportTest { - - static final String LANGUAGE_KEY_1 = "lKey1"; - static final String LANGUAGE_KEY_2 = "lKey2"; - - static final double[] RATING_GRID = new double[] {0.1, 0.2, 0.5, 1}; - - static final long DEV_COST_LANGUAGE_1 = 30; - static final long DEV_COST_LANGUAGE_2 = 42; - - static final int PROJECT_REF = 1; - static final int MODULE_REF = 12; - static final int DIRECTORY_REF = 123; - static final int FILE_1_REF = 1231; - static final int FILE_2_REF = 1232; - - static final Component ROOT_PROJECT = builder(Component.Type.PROJECT, PROJECT_REF).setKey("project") - .addChildren( - builder(MODULE, MODULE_REF).setKey("module") - .addChildren( - builder(DIRECTORY, DIRECTORY_REF).setKey("directory") - .addChildren( - builder(FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1)).setKey("file1").build(), - builder(FILE, FILE_2_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1)).setKey("file2").build()) - .build()) - .build()) - .build(); - - @Rule - public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); - - @Rule - public MetricRepositoryRule metricRepository = new MetricRepositoryRule() - .add(NCLOC) - .add(DEVELOPMENT_COST) - .add(TECHNICAL_DEBT) - .add(SQALE_DEBT_RATIO) - .add(SQALE_RATING) - .add(EFFORT_TO_REACH_MAINTAINABILITY_RATING_A); - - @Rule - public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - - @Rule - public ComponentIssuesRepositoryRule componentIssuesRepositoryRule = new ComponentIssuesRepositoryRule(treeRootHolder); - - private RatingSettings ratingSettings = mock(RatingSettings.class); - - private VisitorsCrawler underTest; - - @Before - public void setUp() { - // assumes rating configuration is consistent - when(ratingSettings.getRatingGrid()).thenReturn(new RatingGrid(RATING_GRID)); - when(ratingSettings.getDevCost(LANGUAGE_KEY_1)).thenReturn(DEV_COST_LANGUAGE_1); - when(ratingSettings.getDevCost(LANGUAGE_KEY_2)).thenReturn(DEV_COST_LANGUAGE_2); - - underTest = new VisitorsCrawler(singletonList(new MaintainabilityMeasuresVisitor(metricRepository, measureRepository, ratingSettings))); - } - - @Test - public void measures_created_for_project_are_all_zero_when_they_have_no_FILE_child() { - ReportComponent root = builder(PROJECT, 1).build(); - treeRootHolder.setRoot(root); - - underTest.visit(root); - - assertThat(toEntries(measureRepository.getRawMeasures(root))) - .containsOnly( - entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create("0")), - entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(0d, 1)), - entryOf(SQALE_RATING_KEY, createMaintainabilityRatingMeasure(A)), - entryOf(EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, newMeasureBuilder().create(0L))); - } - - @Test - public void compute_development_cost() { - ReportComponent root = builder(PROJECT, 1) - .addChildren( - builder(MODULE, 11) - .addChildren( - builder(DIRECTORY, 111) - .addChildren( - createFileComponent(LANGUAGE_KEY_1, 1111), - createFileComponent(LANGUAGE_KEY_2, 1112), - // Unit test should not be ignored - builder(FILE, 1113).setFileAttributes(new FileAttributes(true, LANGUAGE_KEY_1)).build()) - .build(), - builder(DIRECTORY, 112) - .addChildren( - createFileComponent(LANGUAGE_KEY_2, 1121)) - .build()) - .build(), - builder(MODULE, 12) - .addChildren( - builder(DIRECTORY, 121) - .addChildren( - createFileComponent(LANGUAGE_KEY_1, 1211)) - .build(), - builder(DIRECTORY, 122).build()) - .build(), - builder(MODULE, 13).build()) - .build(); - - treeRootHolder.setRoot(root); - - int ncloc1111 = 10; - addRawMeasure(NCLOC_KEY, 1111, ncloc1111); - - int ncloc1112 = 12; - addRawMeasure(NCLOC_KEY, 1112, ncloc1112); - - int ncloc1113 = 15; - addRawMeasure(NCLOC_KEY, 1113, ncloc1113); - - int nclocValue1121 = 30; - addRawMeasure(NCLOC_KEY, 1121, nclocValue1121); - - int ncloc1211 = 20; - addRawMeasure(NCLOC_KEY, 1211, ncloc1211); - - underTest.visit(root); - - // verify measures on files - verifyAddedRawMeasure(1111, DEVELOPMENT_COST_KEY, Long.toString(ncloc1111 * DEV_COST_LANGUAGE_1)); - verifyAddedRawMeasure(1112, DEVELOPMENT_COST_KEY, Long.toString(ncloc1112 * DEV_COST_LANGUAGE_2)); - verifyAddedRawMeasure(1113, DEVELOPMENT_COST_KEY, Long.toString(ncloc1113 * DEV_COST_LANGUAGE_1)); - verifyAddedRawMeasure(1121, DEVELOPMENT_COST_KEY, Long.toString(nclocValue1121 * DEV_COST_LANGUAGE_2)); - verifyAddedRawMeasure(1211, DEVELOPMENT_COST_KEY, Long.toString(ncloc1211 * DEV_COST_LANGUAGE_1)); - - // directory has no children => no file => 0 everywhere and A rating - verifyAddedRawMeasure(122, DEVELOPMENT_COST_KEY, "0"); - - // directory has children => dev cost is aggregated - verifyAddedRawMeasure(111, DEVELOPMENT_COST_KEY, Long.toString( - ncloc1111 * DEV_COST_LANGUAGE_1 + - ncloc1112 * DEV_COST_LANGUAGE_2 + - ncloc1113 * DEV_COST_LANGUAGE_1)); - verifyAddedRawMeasure(112, DEVELOPMENT_COST_KEY, Long.toString(nclocValue1121 * DEV_COST_LANGUAGE_2)); - verifyAddedRawMeasure(121, DEVELOPMENT_COST_KEY, Long.toString(ncloc1211 * DEV_COST_LANGUAGE_1)); - - // just for fun, we didn't define any debt on module => they must all have rating A - verifyAddedRawMeasure(11, DEVELOPMENT_COST_KEY, Long.toString( - ncloc1111 * DEV_COST_LANGUAGE_1 + - ncloc1112 * DEV_COST_LANGUAGE_2 + - ncloc1113 * DEV_COST_LANGUAGE_1 + - nclocValue1121 * DEV_COST_LANGUAGE_2)); - verifyAddedRawMeasure(12, DEVELOPMENT_COST_KEY, Long.toString(ncloc1211 * DEV_COST_LANGUAGE_1)); - verifyAddedRawMeasure(13, DEVELOPMENT_COST_KEY, "0"); - verifyAddedRawMeasure(1, DEVELOPMENT_COST_KEY, Long.toString( - ncloc1111 * DEV_COST_LANGUAGE_1 + - ncloc1112 * DEV_COST_LANGUAGE_2 + - ncloc1113 * DEV_COST_LANGUAGE_1 + - nclocValue1121 * DEV_COST_LANGUAGE_2 + - ncloc1211 * DEV_COST_LANGUAGE_1)); - } - - @Test - public void compute_maintainability_debt_ratio_measure() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - - int file1Ncloc = 10; - addRawMeasure(NCLOC_KEY, FILE_1_REF, file1Ncloc); - long file1MaintainabilityCost = 100L; - addRawMeasure(TECHNICAL_DEBT_KEY, FILE_1_REF, file1MaintainabilityCost); - - int file2Ncloc = 5; - addRawMeasure(NCLOC_KEY, FILE_2_REF, file2Ncloc); - long file2MaintainabilityCost = 1L; - addRawMeasure(TECHNICAL_DEBT_KEY, FILE_2_REF, file2MaintainabilityCost); - - long directoryMaintainabilityCost = 100L; - addRawMeasure(TECHNICAL_DEBT_KEY, DIRECTORY_REF, directoryMaintainabilityCost); - - long moduleMaintainabilityCost = 100L; - addRawMeasure(TECHNICAL_DEBT_KEY, MODULE_REF, moduleMaintainabilityCost); - - long projectMaintainabilityCost = 1000L; - addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_REF, projectMaintainabilityCost); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(FILE_1_REF, SQALE_DEBT_RATIO_KEY, file1MaintainabilityCost * 1d / (file1Ncloc * DEV_COST_LANGUAGE_1) * 100); - verifyAddedRawMeasure(FILE_2_REF, SQALE_DEBT_RATIO_KEY, file2MaintainabilityCost * 1d / (file2Ncloc * DEV_COST_LANGUAGE_1) * 100); - verifyAddedRawMeasure(DIRECTORY_REF, SQALE_DEBT_RATIO_KEY, directoryMaintainabilityCost * 1d / ((file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1) * 100); - verifyAddedRawMeasure(MODULE_REF, SQALE_DEBT_RATIO_KEY, moduleMaintainabilityCost * 1d / ((file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1) * 100); - verifyAddedRawMeasure(PROJECT_REF, SQALE_DEBT_RATIO_KEY, projectMaintainabilityCost * 1d / ((file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1) * 100); - } - - @Test - public void compute_maintainability_rating_measure() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - - addRawMeasure(NCLOC_KEY, FILE_1_REF, 10); - addRawMeasure(TECHNICAL_DEBT_KEY, FILE_1_REF, 100L); - - addRawMeasure(NCLOC_KEY, FILE_2_REF, 5); - addRawMeasure(TECHNICAL_DEBT_KEY, FILE_2_REF, 1L); - - addRawMeasure(TECHNICAL_DEBT_KEY, DIRECTORY_REF, 100L); - addRawMeasure(TECHNICAL_DEBT_KEY, MODULE_REF, 100L); - addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_REF, 1000L); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(FILE_1_REF, SQALE_RATING_KEY, C); - verifyAddedRawMeasure(FILE_2_REF, SQALE_RATING_KEY, A); - verifyAddedRawMeasure(DIRECTORY_REF, SQALE_RATING_KEY, C); - verifyAddedRawMeasure(MODULE_REF, SQALE_RATING_KEY, C); - verifyAddedRawMeasure(PROJECT_REF, SQALE_RATING_KEY, E); - } - - @Test - public void compute_effort_to_maintainability_rating_A_measure() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - - int file1Ncloc = 10; - long file1Effort = 100L; - addRawMeasure(NCLOC_KEY, FILE_1_REF, file1Ncloc); - addRawMeasure(TECHNICAL_DEBT_KEY, FILE_1_REF, file1Effort); - - int file2Ncloc = 5; - long file2Effort = 20L; - addRawMeasure(NCLOC_KEY, FILE_2_REF, file2Ncloc); - addRawMeasure(TECHNICAL_DEBT_KEY, FILE_2_REF, file2Effort); - - long dirEffort = 120L; - addRawMeasure(TECHNICAL_DEBT_KEY, DIRECTORY_REF, dirEffort); - - long moduleEffort = 120L; - addRawMeasure(TECHNICAL_DEBT_KEY, MODULE_REF, moduleEffort); - - long projectEffort = 150L; - addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_REF, projectEffort); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(FILE_1_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, - (long) (file1Effort - RATING_GRID[0] * file1Ncloc * DEV_COST_LANGUAGE_1)); - verifyAddedRawMeasure(FILE_2_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, - (long) (file2Effort - RATING_GRID[0] * file2Ncloc * DEV_COST_LANGUAGE_1)); - verifyAddedRawMeasure(DIRECTORY_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, - (long) (dirEffort - RATING_GRID[0] * (file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1)); - verifyAddedRawMeasure(MODULE_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, - (long) (moduleEffort - RATING_GRID[0] * (file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1)); - verifyAddedRawMeasure(PROJECT_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, - (long) (projectEffort - RATING_GRID[0] * (file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1)); - } - - @Test - public void compute_0_effort_to_maintainability_rating_A_when_effort_is_lower_than_dev_cost() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - - addRawMeasure(NCLOC_KEY, FILE_1_REF, 10); - addRawMeasure(TECHNICAL_DEBT_KEY, FILE_1_REF, 2L); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(FILE_1_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, 0L); - } - - @Test - public void effort_to_maintainability_rating_A_is_same_as_effort_when_no_dev_cost() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - - addRawMeasure(TECHNICAL_DEBT_KEY, FILE_1_REF, 100L); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(FILE_1_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, 100); - } - - private void addRawMeasure(String metricKey, int componentRef, long value) { - measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value)); - } - - private void addRawMeasure(String metricKey, int componentRef, int value) { - measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value)); - } - - private void verifyAddedRawMeasure(int componentRef, String metricKey, long value) { - assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(value))); - } - - private void verifyAddedRawMeasure(int componentRef, String metricKey, double value) { - assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(value, 1))); - } - - private void verifyAddedRawMeasure(int componentRef, String metricKey, Rating rating) { - assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(rating.getIndex(), rating.name()))); - } - - private void verifyAddedRawMeasure(int componentRef, String metricKey, String value) { - assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(value))); - } - - private static ReportComponent createFileComponent(String languageKey1, int fileRef) { - return builder(FILE, fileRef).setFileAttributes(new FileAttributes(false, languageKey1)).build(); - } - - private static Measure createMaintainabilityRatingMeasure(Rating rating) { - return newMeasureBuilder().create(rating.getIndex(), rating.name()); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorForViewsTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorForViewsTest.java deleted file mode 100644 index bbc984eedc7..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorForViewsTest.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * 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.qualitymodel; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; -import org.sonar.server.computation.task.projectanalysis.component.ViewsComponent; -import org.sonar.server.computation.task.projectanalysis.component.VisitorsCrawler; -import org.sonar.server.computation.task.projectanalysis.measure.Measure; -import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.api.measures.CoreMetrics.DEVELOPMENT_COST; -import static org.sonar.api.measures.CoreMetrics.DEVELOPMENT_COST_KEY; -import static org.sonar.api.measures.CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A; -import static org.sonar.api.measures.CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY; -import static org.sonar.api.measures.CoreMetrics.NCLOC; -import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING; -import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING; -import static org.sonar.api.measures.CoreMetrics.SQALE_DEBT_RATIO; -import static org.sonar.api.measures.CoreMetrics.SQALE_DEBT_RATIO_KEY; -import static org.sonar.api.measures.CoreMetrics.SQALE_RATING; -import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY; -import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT; -import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_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; -import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.VIEW; -import static org.sonar.server.computation.task.projectanalysis.component.ViewsComponent.builder; -import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; -import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.entryOf; -import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.B; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.D; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.E; - -public class MaintainabilityMeasuresVisitorForViewsTest { - - private static final double[] RATING_GRID = new double[] {34, 50, 362, 900, 36258}; - - private static final int ROOT_REF = 1; - private static final int SUBVIEW_REF = 11; - private static final int SUB_SUBVIEW_1_REF = 111; - private static final int SUB_SUBVIEW_2_REF = 112; - private static final int PROJECT_VIEW_1_REF = 1111; - private static final int PROJECT_VIEW_2_REF = 1112; - private static final int PROJECT_VIEW_3_REF = 1121; - private static final int PROJECT_VIEW_4_REF = 12; - - @Rule - public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule() - .setRoot(builder(VIEW, ROOT_REF) - .addChildren( - builder(SUBVIEW, SUBVIEW_REF) - .addChildren( - builder(SUBVIEW, SUB_SUBVIEW_1_REF) - .addChildren( - builder(PROJECT_VIEW, PROJECT_VIEW_1_REF).build(), - builder(PROJECT_VIEW, PROJECT_VIEW_2_REF).build()) - .build(), - builder(SUBVIEW, SUB_SUBVIEW_2_REF) - .addChildren( - builder(PROJECT_VIEW, PROJECT_VIEW_3_REF).build()) - .build()) - .build(), - builder(PROJECT_VIEW, PROJECT_VIEW_4_REF).build()) - .build()); - - @Rule - public MetricRepositoryRule metricRepository = new MetricRepositoryRule() - .add(NCLOC) - .add(DEVELOPMENT_COST) - .add(TECHNICAL_DEBT) - .add(SQALE_DEBT_RATIO) - .add(SQALE_RATING) - .add(EFFORT_TO_REACH_MAINTAINABILITY_RATING_A) - .add(RELIABILITY_RATING) - .add(SECURITY_RATING); - - @Rule - public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - - private RatingSettings ratingSettings = mock(RatingSettings.class); - - private VisitorsCrawler underTest; - - @Before - public void setUp() { - when(ratingSettings.getRatingGrid()).thenReturn(new RatingGrid(RATING_GRID)); - underTest = new VisitorsCrawler(singletonList(new MaintainabilityMeasuresVisitor(metricRepository, measureRepository, ratingSettings))); - } - - @Test - public void measures_created_for_view_are_all_zero_when_no_child() { - ViewsComponent root = builder(VIEW, 1).build(); - treeRootHolder.setRoot(root); - - underTest.visit(root); - - assertThat(toEntries(measureRepository.getRawMeasures(root))) - .containsOnly( - entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create("0")), - entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(0d, 1)), - entryOf(SQALE_RATING_KEY, createMaintainabilityRatingMeasure(A)), - entryOf(EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, newMeasureBuilder().create(0L))); - } - - @Test - public void verify_aggregation_of_developmentCost_and_value_of_measures_computed_from_that() { - long debtRoot = 9999l; - long debtSubView = 96325l; - long debtSubSubView1 = 96325l; - long debtSubSubView2 = 99633l; - - addRawMeasure(TECHNICAL_DEBT_KEY, ROOT_REF, debtRoot); - addRawMeasure(TECHNICAL_DEBT_KEY, SUBVIEW_REF, debtSubView); - addRawMeasure(TECHNICAL_DEBT_KEY, SUB_SUBVIEW_1_REF, debtSubSubView1); - addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_VIEW_1_REF, 66000l); - addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_VIEW_2_REF, 4200l); - addRawMeasure(TECHNICAL_DEBT_KEY, SUB_SUBVIEW_2_REF, debtSubSubView2); - addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_VIEW_3_REF, 25200l); - addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_VIEW_4_REF, 33000l); - - addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_1_REF, "40"); - addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_2_REF, "70"); - addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_3_REF, "50"); - addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_4_REF, "100"); - - underTest.visit(treeRootHolder.getRoot()); - - assertNoNewRawMeasureOnProjectViews(); - assertNewRawMeasures(SUB_SUBVIEW_1_REF, debtSubSubView1, 110, D); - assertNewRawMeasures(SUB_SUBVIEW_2_REF, debtSubSubView2, 50, E); - assertNewRawMeasures(SUBVIEW_REF, debtSubView, 160, D); - assertNewRawMeasures(ROOT_REF, debtRoot, 260, B); - } - - @Test - public void compute_effort_to_maintainability_rating_A_measure() throws Exception { - treeRootHolder.setRoot(treeRootHolder.getRoot()); - - long projectView1DevCosts = 40L; - addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_1_REF, Long.toString(projectView1DevCosts)); - long projectView2DevCosts = 70L; - addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_2_REF, Long.toString(projectView2DevCosts)); - long projectView3DevCosts = 50L; - addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_3_REF, Long.toString(projectView3DevCosts)); - long projectView4DevCosts = 100L; - addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_4_REF, Long.toString(projectView4DevCosts)); - - long subSubView1Effort = 10000L; - addRawMeasure(TECHNICAL_DEBT_KEY, SUB_SUBVIEW_1_REF, subSubView1Effort); - - long subSubView2Effort = 20000L; - addRawMeasure(TECHNICAL_DEBT_KEY, SUB_SUBVIEW_2_REF, subSubView2Effort); - - long subViewEffort = 30000L; - addRawMeasure(TECHNICAL_DEBT_KEY, SUBVIEW_REF, subViewEffort); - - long viewEffort = 35000L; - addRawMeasure(TECHNICAL_DEBT_KEY, ROOT_REF, viewEffort); - - underTest.visit(treeRootHolder.getRoot()); - - verifyRawMeasure(SUB_SUBVIEW_1_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, - (long) (subSubView1Effort - RATING_GRID[0] * (projectView1DevCosts + projectView2DevCosts))); - verifyRawMeasure(SUB_SUBVIEW_2_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, - (long) (subSubView2Effort - RATING_GRID[0] * projectView3DevCosts)); - verifyRawMeasure(SUBVIEW_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, - (long) (subViewEffort - RATING_GRID[0] * (projectView1DevCosts + projectView2DevCosts + projectView3DevCosts))); - verifyRawMeasure(ROOT_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, - (long) (viewEffort - RATING_GRID[0] * (projectView1DevCosts + projectView2DevCosts + projectView3DevCosts + - projectView4DevCosts))); - } - - private void assertNewRawMeasures(int componentRef, long debt, long devCost, Rating rating) { - assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains( - entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create(String.valueOf(devCost))), - entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(debt / (double) devCost * 100.0, 1)), - entryOf(SQALE_RATING_KEY, createMaintainabilityRatingMeasure(rating))); - } - - private void assertNoNewRawMeasureOnProjectViews() { - assertNoNewRawMeasure(PROJECT_VIEW_1_REF); - assertNoNewRawMeasure(PROJECT_VIEW_2_REF); - assertNoNewRawMeasure(PROJECT_VIEW_3_REF); - assertNoNewRawMeasure(PROJECT_VIEW_4_REF); - } - - private void addRawMeasure(String metricKey, int componentRef, String value) { - measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value)); - } - - private void addRawMeasure(String metricKey, int componentRef, long value) { - measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value)); - } - - private void assertNoNewRawMeasure(int componentRef) { - assertThat(measureRepository.getAddedRawMeasures(componentRef).isEmpty()).isTrue(); - } - - private void verifyRawMeasure(int componentRef, String metricKey, long value) { - assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(value))); - } - - private static Measure createMaintainabilityRatingMeasure(Rating rating) { - return newMeasureBuilder().create(rating.getIndex(), rating.name()); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java new file mode 100644 index 00000000000..53acf238294 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java @@ -0,0 +1,368 @@ +/* + * 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.qualitymodel; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.server.computation.task.projectanalysis.component.Component; +import org.sonar.server.computation.task.projectanalysis.component.FileAttributes; +import org.sonar.server.computation.task.projectanalysis.component.ReportComponent; +import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; +import org.sonar.server.computation.task.projectanalysis.component.VisitorsCrawler; +import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRepositoryRule; +import org.sonar.server.computation.task.projectanalysis.measure.Measure; +import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule; +import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; +import org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating; + +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.measures.CoreMetrics.DEVELOPMENT_COST; +import static org.sonar.api.measures.CoreMetrics.DEVELOPMENT_COST_KEY; +import static org.sonar.api.measures.CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A; +import static org.sonar.api.measures.CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_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.SQALE_DEBT_RATIO; +import static org.sonar.api.measures.CoreMetrics.SQALE_DEBT_RATIO_KEY; +import static org.sonar.api.measures.CoreMetrics.SQALE_RATING; +import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY; +import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT; +import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY; +import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.DIRECTORY; +import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE; +import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.MODULE; +import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT; +import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder; +import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; +import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.entryOf; +import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries; +import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.A; +import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.C; +import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.E; + +public class MaintainabilityMeasuresVisitorTest { + + static final String LANGUAGE_KEY_1 = "lKey1"; + static final String LANGUAGE_KEY_2 = "lKey2"; + + static final double[] RATING_GRID = new double[] {0.1, 0.2, 0.5, 1}; + + static final long DEV_COST_LANGUAGE_1 = 30; + static final long DEV_COST_LANGUAGE_2 = 42; + + static final int PROJECT_REF = 1; + static final int MODULE_REF = 12; + static final int DIRECTORY_REF = 123; + static final int FILE_1_REF = 1231; + static final int FILE_2_REF = 1232; + + static final Component ROOT_PROJECT = builder(Component.Type.PROJECT, PROJECT_REF).setKey("project") + .addChildren( + builder(MODULE, MODULE_REF).setKey("module") + .addChildren( + builder(DIRECTORY, DIRECTORY_REF).setKey("directory") + .addChildren( + builder(FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1)).setKey("file1").build(), + builder(FILE, FILE_2_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1)).setKey("file2").build()) + .build()) + .build()) + .build(); + + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); + + @Rule + public MetricRepositoryRule metricRepository = new MetricRepositoryRule() + .add(NCLOC) + .add(DEVELOPMENT_COST) + .add(TECHNICAL_DEBT) + .add(SQALE_DEBT_RATIO) + .add(SQALE_RATING) + .add(EFFORT_TO_REACH_MAINTAINABILITY_RATING_A); + + @Rule + public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); + + @Rule + public ComponentIssuesRepositoryRule componentIssuesRepositoryRule = new ComponentIssuesRepositoryRule(treeRootHolder); + + private RatingSettings ratingSettings = mock(RatingSettings.class); + + private VisitorsCrawler underTest; + + @Before + public void setUp() { + // assumes rating configuration is consistent + when(ratingSettings.getRatingGrid()).thenReturn(new RatingGrid(RATING_GRID)); + when(ratingSettings.getDevCost(LANGUAGE_KEY_1)).thenReturn(DEV_COST_LANGUAGE_1); + when(ratingSettings.getDevCost(LANGUAGE_KEY_2)).thenReturn(DEV_COST_LANGUAGE_2); + + underTest = new VisitorsCrawler(singletonList(new MaintainabilityMeasuresVisitor(metricRepository, measureRepository, ratingSettings))); + } + + @Test + public void measures_created_for_project_are_all_zero_when_they_have_no_FILE_child() { + ReportComponent root = builder(PROJECT, 1).build(); + treeRootHolder.setRoot(root); + + underTest.visit(root); + + assertThat(toEntries(measureRepository.getRawMeasures(root))) + .containsOnly( + entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create("0")), + entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(0d, 1)), + entryOf(SQALE_RATING_KEY, createMaintainabilityRatingMeasure(A)), + entryOf(EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, newMeasureBuilder().create(0L))); + } + + @Test + public void compute_development_cost() { + ReportComponent root = builder(PROJECT, 1) + .addChildren( + builder(MODULE, 11) + .addChildren( + builder(DIRECTORY, 111) + .addChildren( + createFileComponent(LANGUAGE_KEY_1, 1111), + createFileComponent(LANGUAGE_KEY_2, 1112), + // Unit test should not be ignored + builder(FILE, 1113).setFileAttributes(new FileAttributes(true, LANGUAGE_KEY_1)).build()) + .build(), + builder(DIRECTORY, 112) + .addChildren( + createFileComponent(LANGUAGE_KEY_2, 1121)) + .build()) + .build(), + builder(MODULE, 12) + .addChildren( + builder(DIRECTORY, 121) + .addChildren( + createFileComponent(LANGUAGE_KEY_1, 1211)) + .build(), + builder(DIRECTORY, 122).build()) + .build(), + builder(MODULE, 13).build()) + .build(); + + treeRootHolder.setRoot(root); + + int ncloc1111 = 10; + addRawMeasure(NCLOC_KEY, 1111, ncloc1111); + + int ncloc1112 = 12; + addRawMeasure(NCLOC_KEY, 1112, ncloc1112); + + int ncloc1113 = 15; + addRawMeasure(NCLOC_KEY, 1113, ncloc1113); + + int nclocValue1121 = 30; + addRawMeasure(NCLOC_KEY, 1121, nclocValue1121); + + int ncloc1211 = 20; + addRawMeasure(NCLOC_KEY, 1211, ncloc1211); + + underTest.visit(root); + + // verify measures on files + verifyAddedRawMeasure(1111, DEVELOPMENT_COST_KEY, Long.toString(ncloc1111 * DEV_COST_LANGUAGE_1)); + verifyAddedRawMeasure(1112, DEVELOPMENT_COST_KEY, Long.toString(ncloc1112 * DEV_COST_LANGUAGE_2)); + verifyAddedRawMeasure(1113, DEVELOPMENT_COST_KEY, Long.toString(ncloc1113 * DEV_COST_LANGUAGE_1)); + verifyAddedRawMeasure(1121, DEVELOPMENT_COST_KEY, Long.toString(nclocValue1121 * DEV_COST_LANGUAGE_2)); + verifyAddedRawMeasure(1211, DEVELOPMENT_COST_KEY, Long.toString(ncloc1211 * DEV_COST_LANGUAGE_1)); + + // directory has no children => no file => 0 everywhere and A rating + verifyAddedRawMeasure(122, DEVELOPMENT_COST_KEY, "0"); + + // directory has children => dev cost is aggregated + verifyAddedRawMeasure(111, DEVELOPMENT_COST_KEY, Long.toString( + ncloc1111 * DEV_COST_LANGUAGE_1 + + ncloc1112 * DEV_COST_LANGUAGE_2 + + ncloc1113 * DEV_COST_LANGUAGE_1)); + verifyAddedRawMeasure(112, DEVELOPMENT_COST_KEY, Long.toString(nclocValue1121 * DEV_COST_LANGUAGE_2)); + verifyAddedRawMeasure(121, DEVELOPMENT_COST_KEY, Long.toString(ncloc1211 * DEV_COST_LANGUAGE_1)); + + // just for fun, we didn't define any debt on module => they must all have rating A + verifyAddedRawMeasure(11, DEVELOPMENT_COST_KEY, Long.toString( + ncloc1111 * DEV_COST_LANGUAGE_1 + + ncloc1112 * DEV_COST_LANGUAGE_2 + + ncloc1113 * DEV_COST_LANGUAGE_1 + + nclocValue1121 * DEV_COST_LANGUAGE_2)); + verifyAddedRawMeasure(12, DEVELOPMENT_COST_KEY, Long.toString(ncloc1211 * DEV_COST_LANGUAGE_1)); + verifyAddedRawMeasure(13, DEVELOPMENT_COST_KEY, "0"); + verifyAddedRawMeasure(1, DEVELOPMENT_COST_KEY, Long.toString( + ncloc1111 * DEV_COST_LANGUAGE_1 + + ncloc1112 * DEV_COST_LANGUAGE_2 + + ncloc1113 * DEV_COST_LANGUAGE_1 + + nclocValue1121 * DEV_COST_LANGUAGE_2 + + ncloc1211 * DEV_COST_LANGUAGE_1)); + } + + @Test + public void compute_maintainability_debt_ratio_measure() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + + int file1Ncloc = 10; + addRawMeasure(NCLOC_KEY, FILE_1_REF, file1Ncloc); + long file1MaintainabilityCost = 100L; + addRawMeasure(TECHNICAL_DEBT_KEY, FILE_1_REF, file1MaintainabilityCost); + + int file2Ncloc = 5; + addRawMeasure(NCLOC_KEY, FILE_2_REF, file2Ncloc); + long file2MaintainabilityCost = 1L; + addRawMeasure(TECHNICAL_DEBT_KEY, FILE_2_REF, file2MaintainabilityCost); + + long directoryMaintainabilityCost = 100L; + addRawMeasure(TECHNICAL_DEBT_KEY, DIRECTORY_REF, directoryMaintainabilityCost); + + long moduleMaintainabilityCost = 100L; + addRawMeasure(TECHNICAL_DEBT_KEY, MODULE_REF, moduleMaintainabilityCost); + + long projectMaintainabilityCost = 1000L; + addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_REF, projectMaintainabilityCost); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(FILE_1_REF, SQALE_DEBT_RATIO_KEY, file1MaintainabilityCost * 1d / (file1Ncloc * DEV_COST_LANGUAGE_1) * 100); + verifyAddedRawMeasure(FILE_2_REF, SQALE_DEBT_RATIO_KEY, file2MaintainabilityCost * 1d / (file2Ncloc * DEV_COST_LANGUAGE_1) * 100); + verifyAddedRawMeasure(DIRECTORY_REF, SQALE_DEBT_RATIO_KEY, directoryMaintainabilityCost * 1d / ((file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1) * 100); + verifyAddedRawMeasure(MODULE_REF, SQALE_DEBT_RATIO_KEY, moduleMaintainabilityCost * 1d / ((file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1) * 100); + verifyAddedRawMeasure(PROJECT_REF, SQALE_DEBT_RATIO_KEY, projectMaintainabilityCost * 1d / ((file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1) * 100); + } + + @Test + public void compute_maintainability_rating_measure() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + + addRawMeasure(NCLOC_KEY, FILE_1_REF, 10); + addRawMeasure(TECHNICAL_DEBT_KEY, FILE_1_REF, 100L); + + addRawMeasure(NCLOC_KEY, FILE_2_REF, 5); + addRawMeasure(TECHNICAL_DEBT_KEY, FILE_2_REF, 1L); + + addRawMeasure(TECHNICAL_DEBT_KEY, DIRECTORY_REF, 100L); + addRawMeasure(TECHNICAL_DEBT_KEY, MODULE_REF, 100L); + addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_REF, 1000L); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(FILE_1_REF, SQALE_RATING_KEY, C); + verifyAddedRawMeasure(FILE_2_REF, SQALE_RATING_KEY, A); + verifyAddedRawMeasure(DIRECTORY_REF, SQALE_RATING_KEY, C); + verifyAddedRawMeasure(MODULE_REF, SQALE_RATING_KEY, C); + verifyAddedRawMeasure(PROJECT_REF, SQALE_RATING_KEY, E); + } + + @Test + public void compute_effort_to_maintainability_rating_A_measure() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + + int file1Ncloc = 10; + long file1Effort = 100L; + addRawMeasure(NCLOC_KEY, FILE_1_REF, file1Ncloc); + addRawMeasure(TECHNICAL_DEBT_KEY, FILE_1_REF, file1Effort); + + int file2Ncloc = 5; + long file2Effort = 20L; + addRawMeasure(NCLOC_KEY, FILE_2_REF, file2Ncloc); + addRawMeasure(TECHNICAL_DEBT_KEY, FILE_2_REF, file2Effort); + + long dirEffort = 120L; + addRawMeasure(TECHNICAL_DEBT_KEY, DIRECTORY_REF, dirEffort); + + long moduleEffort = 120L; + addRawMeasure(TECHNICAL_DEBT_KEY, MODULE_REF, moduleEffort); + + long projectEffort = 150L; + addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_REF, projectEffort); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(FILE_1_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, + (long) (file1Effort - RATING_GRID[0] * file1Ncloc * DEV_COST_LANGUAGE_1)); + verifyAddedRawMeasure(FILE_2_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, + (long) (file2Effort - RATING_GRID[0] * file2Ncloc * DEV_COST_LANGUAGE_1)); + verifyAddedRawMeasure(DIRECTORY_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, + (long) (dirEffort - RATING_GRID[0] * (file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1)); + verifyAddedRawMeasure(MODULE_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, + (long) (moduleEffort - RATING_GRID[0] * (file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1)); + verifyAddedRawMeasure(PROJECT_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, + (long) (projectEffort - RATING_GRID[0] * (file1Ncloc + file2Ncloc) * DEV_COST_LANGUAGE_1)); + } + + @Test + public void compute_0_effort_to_maintainability_rating_A_when_effort_is_lower_than_dev_cost() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + + addRawMeasure(NCLOC_KEY, FILE_1_REF, 10); + addRawMeasure(TECHNICAL_DEBT_KEY, FILE_1_REF, 2L); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(FILE_1_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, 0L); + } + + @Test + public void effort_to_maintainability_rating_A_is_same_as_effort_when_no_dev_cost() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + + addRawMeasure(TECHNICAL_DEBT_KEY, FILE_1_REF, 100L); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(FILE_1_REF, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY, 100); + } + + private void addRawMeasure(String metricKey, int componentRef, long value) { + measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value)); + } + + private void addRawMeasure(String metricKey, int componentRef, int value) { + measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value)); + } + + private void verifyAddedRawMeasure(int componentRef, String metricKey, long value) { + assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(value))); + } + + private void verifyAddedRawMeasure(int componentRef, String metricKey, double value) { + assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(value, 1))); + } + + private void verifyAddedRawMeasure(int componentRef, String metricKey, Rating rating) { + assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(rating.getIndex(), rating.name()))); + } + + private void verifyAddedRawMeasure(int componentRef, String metricKey, String value) { + assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(value))); + } + + private static ReportComponent createFileComponent(String languageKey1, int fileRef) { + return builder(FILE, fileRef).setFileAttributes(new FileAttributes(false, languageKey1)).build(); + } + + private static Measure createMaintainabilityRatingMeasure(Rating rating) { + return newMeasureBuilder().create(rating.getIndex(), rating.name()); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForReportTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForReportTest.java deleted file mode 100644 index 7f69d94b10b..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForReportTest.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * 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.qualitymodel; - -import java.util.Arrays; -import java.util.Date; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.rules.RuleType; -import org.sonar.api.utils.Duration; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.core.util.Uuids; -import org.sonar.server.computation.task.projectanalysis.component.Component; -import org.sonar.server.computation.task.projectanalysis.component.FileAttributes; -import org.sonar.server.computation.task.projectanalysis.component.ReportComponent; -import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; -import org.sonar.server.computation.task.projectanalysis.component.VisitorsCrawler; -import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.issue.FillComponentIssuesVisitorRule; -import org.sonar.server.computation.task.projectanalysis.measure.Measure; -import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.issue.Issue.RESOLUTION_FIXED; -import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING; -import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY; -import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING; -import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING_KEY; -import static org.sonar.api.rule.Severity.BLOCKER; -import static org.sonar.api.rule.Severity.CRITICAL; -import static org.sonar.api.rule.Severity.INFO; -import static org.sonar.api.rule.Severity.MAJOR; -import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.VULNERABILITY; -import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.DIRECTORY; -import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE; -import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.MODULE; -import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT; -import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder; -import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; -import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.entryOf; -import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.B; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.D; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.E; - -public class ReliabilityAndSecurityRatingMeasuresVisitorForReportTest { - - static final String LANGUAGE_KEY_1 = "lKey1"; - - static final int PROJECT_REF = 1; - static final int MODULE_REF = 12; - static final int DIRECTORY_REF = 123; - static final int FILE_1_REF = 1231; - static final int FILE_2_REF = 1232; - - static final Component ROOT_PROJECT = builder(Component.Type.PROJECT, PROJECT_REF).setKey("project") - .addChildren( - builder(MODULE, MODULE_REF).setKey("module") - .addChildren( - builder(DIRECTORY, DIRECTORY_REF).setKey("directory") - .addChildren( - builder(FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1)).setKey("file1").build(), - builder(FILE, FILE_2_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1)).setKey("file2").build()) - .build()) - .build()) - .build(); - - @Rule - public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); - - @Rule - public MetricRepositoryRule metricRepository = new MetricRepositoryRule() - .add(RELIABILITY_RATING) - .add(SECURITY_RATING); - - @Rule - public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - - @Rule - public ComponentIssuesRepositoryRule componentIssuesRepositoryRule = new ComponentIssuesRepositoryRule(treeRootHolder); - - @Rule - public FillComponentIssuesVisitorRule fillComponentIssuesVisitorRule = new FillComponentIssuesVisitorRule(componentIssuesRepositoryRule, treeRootHolder); - - VisitorsCrawler underTest = new VisitorsCrawler( - Arrays.asList(fillComponentIssuesVisitorRule, new ReliabilityAndSecurityRatingMeasuresVisitor(metricRepository, measureRepository, componentIssuesRepositoryRule))); - - @Test - public void measures_created_for_project_are_all_A_when_they_have_no_FILE_child() { - ReportComponent root = builder(PROJECT, 1).build(); - treeRootHolder.setRoot(root); - - underTest.visit(root); - - assertThat(toEntries(measureRepository.getRawMeasures(root))) - .containsOnly( - entryOf(RELIABILITY_RATING_KEY, createRatingMeasure(A)), - entryOf(SECURITY_RATING_KEY, createRatingMeasure(A))); - } - - @Test - public void compute_reliability_rating() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, MAJOR), newBugIssue(1L, MAJOR), - // Should not be taken into account - newVulnerabilityIssue(5L, MINOR)); - fillComponentIssuesVisitorRule.setIssues(FILE_2_REF, newBugIssue(2L, CRITICAL), newBugIssue(3L, MINOR), - // Should not be taken into account - newBugIssue(10L, BLOCKER).setResolution(RESOLUTION_FIXED)); - fillComponentIssuesVisitorRule.setIssues(MODULE_REF, newBugIssue(7L, BLOCKER)); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(FILE_1_REF, RELIABILITY_RATING_KEY, C); - verifyAddedRawMeasure(FILE_2_REF, RELIABILITY_RATING_KEY, D); - verifyAddedRawMeasure(DIRECTORY_REF, RELIABILITY_RATING_KEY, D); - verifyAddedRawMeasure(MODULE_REF, RELIABILITY_RATING_KEY, E); - verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, E); - } - - @Test - public void compute_security_rating() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newVulnerabilityIssue(10L, MAJOR), newVulnerabilityIssue(1L, MAJOR), - // Should not be taken into account - newBugIssue(1L, MAJOR)); - fillComponentIssuesVisitorRule.setIssues(FILE_2_REF, newVulnerabilityIssue(2L, CRITICAL), newVulnerabilityIssue(3L, MINOR), - // Should not be taken into account - newVulnerabilityIssue(10L, BLOCKER).setResolution(RESOLUTION_FIXED)); - fillComponentIssuesVisitorRule.setIssues(MODULE_REF, newVulnerabilityIssue(7L, BLOCKER)); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(FILE_1_REF, SECURITY_RATING_KEY, C); - verifyAddedRawMeasure(FILE_2_REF, SECURITY_RATING_KEY, D); - verifyAddedRawMeasure(DIRECTORY_REF, SECURITY_RATING_KEY, D); - verifyAddedRawMeasure(MODULE_REF, SECURITY_RATING_KEY, E); - verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, E); - } - - @Test - public void compute_E_reliability_and_security_rating_on_blocker_issue() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, BLOCKER), newVulnerabilityIssue(1L, BLOCKER), - // Should not be taken into account - newBugIssue(1L, MAJOR)); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, E); - verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, E); - } - - @Test - public void compute_D_reliability_and_security_rating_on_critical_issue() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, CRITICAL), newVulnerabilityIssue(15L, CRITICAL), - // Should not be taken into account - newCodeSmellIssue(1L, MAJOR)); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, D); - verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, D); - } - - @Test - public void compute_C_reliability_and_security_rating_on_major_issue() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, MAJOR), newVulnerabilityIssue(15L, MAJOR), - // Should not be taken into account - newCodeSmellIssue(1L, MAJOR)); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, C); - verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, C); - } - - @Test - public void compute_B_reliability_and_security_rating_on_minor_issue() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, MINOR), newVulnerabilityIssue(15L, MINOR), - // Should not be taken into account - newCodeSmellIssue(1L, MAJOR)); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, B); - verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, B); - } - - @Test - public void compute_A_reliability_and_security_rating_on_info_issue() throws Exception { - treeRootHolder.setRoot(ROOT_PROJECT); - fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, INFO), newVulnerabilityIssue(15L, INFO), - // Should not be taken into account - newCodeSmellIssue(1L, MAJOR)); - - underTest.visit(ROOT_PROJECT); - - verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, A); - verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, A); - } - - private void verifyAddedRawMeasure(int componentRef, String metricKey, Rating rating) { - assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(rating.getIndex(), rating.name()))); - } - - private static Measure createRatingMeasure(Rating rating) { - return newMeasureBuilder().create(rating.getIndex(), rating.name()); - } - - private static DefaultIssue newBugIssue(long effort, String severity) { - return newIssue(effort, severity, BUG); - } - - private static DefaultIssue newVulnerabilityIssue(long effort, String severity) { - return newIssue(effort, severity, VULNERABILITY); - } - - private static DefaultIssue newCodeSmellIssue(long effort, String severity) { - return newIssue(effort, severity, CODE_SMELL); - } - - private static DefaultIssue newIssue(long effort, String severity, RuleType type) { - return newIssue(severity, type) - .setEffort(Duration.create(effort)); - } - - private static DefaultIssue newIssue(String severity, RuleType type) { - return new DefaultIssue() - .setKey(Uuids.create()) - .setSeverity(severity) - .setType(type) - .setCreationDate(new Date(1000l)); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForViewsTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForViewsTest.java deleted file mode 100644 index 905cd528922..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForViewsTest.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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.qualitymodel; - -import org.junit.Rule; -import org.junit.Test; -import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; -import org.sonar.server.computation.task.projectanalysis.component.ViewsComponent; -import org.sonar.server.computation.task.projectanalysis.component.VisitorsCrawler; -import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.measure.Measure; -import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING; -import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY; -import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING; -import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING_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; -import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.VIEW; -import static org.sonar.server.computation.task.projectanalysis.component.ViewsComponent.builder; -import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; -import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.entryOf; -import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.B; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.D; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.E; - -public class ReliabilityAndSecurityRatingMeasuresVisitorForViewsTest { - - private static final int ROOT_REF = 1; - private static final int SUBVIEW_REF = 11; - private static final int SUB_SUBVIEW_1_REF = 111; - private static final int SUB_SUBVIEW_2_REF = 112; - private static final int PROJECT_VIEW_1_REF = 1111; - private static final int PROJECT_VIEW_2_REF = 1112; - private static final int PROJECT_VIEW_3_REF = 1121; - private static final int PROJECT_VIEW_4_REF = 12; - - @Rule - public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule() - .setRoot(builder(VIEW, ROOT_REF) - .addChildren( - builder(SUBVIEW, SUBVIEW_REF) - .addChildren( - builder(SUBVIEW, SUB_SUBVIEW_1_REF) - .addChildren( - builder(PROJECT_VIEW, PROJECT_VIEW_1_REF).build(), - builder(PROJECT_VIEW, PROJECT_VIEW_2_REF).build()) - .build(), - builder(SUBVIEW, SUB_SUBVIEW_2_REF) - .addChildren( - builder(PROJECT_VIEW, PROJECT_VIEW_3_REF).build()) - .build()) - .build(), - builder(PROJECT_VIEW, PROJECT_VIEW_4_REF).build()) - .build()); - - @Rule - public MetricRepositoryRule metricRepository = new MetricRepositoryRule() - .add(RELIABILITY_RATING) - .add(SECURITY_RATING); - - @Rule - public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - - @Rule - public ComponentIssuesRepositoryRule componentIssuesRepositoryRule = new ComponentIssuesRepositoryRule(treeRootHolder); - - VisitorsCrawler underTest = new VisitorsCrawler( - singletonList(new ReliabilityAndSecurityRatingMeasuresVisitor(metricRepository, measureRepository, componentIssuesRepositoryRule))); - - @Test - public void measures_created_for_view_are_all_zero_when_no_child() { - ViewsComponent root = builder(VIEW, 1).build(); - treeRootHolder.setRoot(root); - - underTest.visit(root); - - assertThat(toEntries(measureRepository.getRawMeasures(root))) - .containsOnly( - entryOf(RELIABILITY_RATING_KEY, createMaintainabilityRatingMeasure(A)), - entryOf(SECURITY_RATING_KEY, createMaintainabilityRatingMeasure(A))); - } - - @Test - public void compute_reliability_rating() throws Exception { - treeRootHolder.setRoot(treeRootHolder.getRoot()); - - addRawMeasure(RELIABILITY_RATING_KEY, PROJECT_VIEW_1_REF, B); - addRawMeasure(RELIABILITY_RATING_KEY, PROJECT_VIEW_2_REF, C); - addRawMeasure(RELIABILITY_RATING_KEY, PROJECT_VIEW_3_REF, D); - addRawMeasure(RELIABILITY_RATING_KEY, PROJECT_VIEW_4_REF, E); - - underTest.visit(treeRootHolder.getRoot()); - - verifyRawMeasure(SUB_SUBVIEW_1_REF, RELIABILITY_RATING_KEY, C); - verifyRawMeasure(SUB_SUBVIEW_2_REF, RELIABILITY_RATING_KEY, D); - verifyRawMeasure(SUBVIEW_REF, RELIABILITY_RATING_KEY, D); - verifyRawMeasure(ROOT_REF, RELIABILITY_RATING_KEY, E); - } - - @Test - public void compute_security_rating() throws Exception { - treeRootHolder.setRoot(treeRootHolder.getRoot()); - - addRawMeasure(SECURITY_RATING_KEY, PROJECT_VIEW_2_REF, B); - addRawMeasure(SECURITY_RATING_KEY, PROJECT_VIEW_1_REF, C); - addRawMeasure(SECURITY_RATING_KEY, PROJECT_VIEW_3_REF, D); - addRawMeasure(SECURITY_RATING_KEY, PROJECT_VIEW_4_REF, E); - - underTest.visit(treeRootHolder.getRoot()); - - verifyRawMeasure(SUB_SUBVIEW_1_REF, SECURITY_RATING_KEY, C); - verifyRawMeasure(SUB_SUBVIEW_2_REF, SECURITY_RATING_KEY, D); - verifyRawMeasure(SUBVIEW_REF, SECURITY_RATING_KEY, D); - verifyRawMeasure(ROOT_REF, SECURITY_RATING_KEY, E); - } - - private void addRawMeasure(String metricKey, int componentRef, Rating value) { - measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value.getIndex(), value.name())); - } - - private void verifyRawMeasure(int componentRef, String metricKey, Rating rating) { - assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(rating.getIndex(), rating.name()))); - } - - private static Measure createMaintainabilityRatingMeasure(Rating rating) { - return newMeasureBuilder().create(rating.getIndex(), rating.name()); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java new file mode 100644 index 00000000000..8ba41fd9195 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java @@ -0,0 +1,264 @@ +/* + * 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.qualitymodel; + +import java.util.Arrays; +import java.util.Date; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.rules.RuleType; +import org.sonar.api.utils.Duration; +import org.sonar.core.issue.DefaultIssue; +import org.sonar.core.util.Uuids; +import org.sonar.server.computation.task.projectanalysis.component.Component; +import org.sonar.server.computation.task.projectanalysis.component.FileAttributes; +import org.sonar.server.computation.task.projectanalysis.component.ReportComponent; +import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; +import org.sonar.server.computation.task.projectanalysis.component.VisitorsCrawler; +import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRepositoryRule; +import org.sonar.server.computation.task.projectanalysis.issue.FillComponentIssuesVisitorRule; +import org.sonar.server.computation.task.projectanalysis.measure.Measure; +import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule; +import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.issue.Issue.RESOLUTION_FIXED; +import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING; +import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY; +import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING; +import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING_KEY; +import static org.sonar.api.rule.Severity.BLOCKER; +import static org.sonar.api.rule.Severity.CRITICAL; +import static org.sonar.api.rule.Severity.INFO; +import static org.sonar.api.rule.Severity.MAJOR; +import static org.sonar.api.rule.Severity.MINOR; +import static org.sonar.api.rules.RuleType.BUG; +import static org.sonar.api.rules.RuleType.CODE_SMELL; +import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.DIRECTORY; +import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE; +import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.MODULE; +import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT; +import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder; +import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; +import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.entryOf; +import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries; +import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating; +import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.A; +import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.B; +import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.C; +import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.D; +import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.E; + +public class ReliabilityAndSecurityRatingMeasuresVisitorTest { + + static final String LANGUAGE_KEY_1 = "lKey1"; + + static final int PROJECT_REF = 1; + static final int MODULE_REF = 12; + static final int DIRECTORY_REF = 123; + static final int FILE_1_REF = 1231; + static final int FILE_2_REF = 1232; + + static final Component ROOT_PROJECT = builder(Component.Type.PROJECT, PROJECT_REF).setKey("project") + .addChildren( + builder(MODULE, MODULE_REF).setKey("module") + .addChildren( + builder(DIRECTORY, DIRECTORY_REF).setKey("directory") + .addChildren( + builder(FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1)).setKey("file1").build(), + builder(FILE, FILE_2_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1)).setKey("file2").build()) + .build()) + .build()) + .build(); + + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); + + @Rule + public MetricRepositoryRule metricRepository = new MetricRepositoryRule() + .add(RELIABILITY_RATING) + .add(SECURITY_RATING); + + @Rule + public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); + + @Rule + public ComponentIssuesRepositoryRule componentIssuesRepositoryRule = new ComponentIssuesRepositoryRule(treeRootHolder); + + @Rule + public FillComponentIssuesVisitorRule fillComponentIssuesVisitorRule = new FillComponentIssuesVisitorRule(componentIssuesRepositoryRule, treeRootHolder); + + VisitorsCrawler underTest = new VisitorsCrawler( + Arrays.asList(fillComponentIssuesVisitorRule, new ReliabilityAndSecurityRatingMeasuresVisitor(metricRepository, measureRepository, componentIssuesRepositoryRule))); + + @Test + public void measures_created_for_project_are_all_A_when_they_have_no_FILE_child() { + ReportComponent root = builder(PROJECT, 1).build(); + treeRootHolder.setRoot(root); + + underTest.visit(root); + + assertThat(toEntries(measureRepository.getRawMeasures(root))) + .containsOnly( + entryOf(RELIABILITY_RATING_KEY, createRatingMeasure(A)), + entryOf(SECURITY_RATING_KEY, createRatingMeasure(A))); + } + + @Test + public void compute_reliability_rating() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, MAJOR), newBugIssue(1L, MAJOR), + // Should not be taken into account + newVulnerabilityIssue(5L, MINOR)); + fillComponentIssuesVisitorRule.setIssues(FILE_2_REF, newBugIssue(2L, CRITICAL), newBugIssue(3L, MINOR), + // Should not be taken into account + newBugIssue(10L, BLOCKER).setResolution(RESOLUTION_FIXED)); + fillComponentIssuesVisitorRule.setIssues(MODULE_REF, newBugIssue(7L, BLOCKER)); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(FILE_1_REF, RELIABILITY_RATING_KEY, C); + verifyAddedRawMeasure(FILE_2_REF, RELIABILITY_RATING_KEY, D); + verifyAddedRawMeasure(DIRECTORY_REF, RELIABILITY_RATING_KEY, D); + verifyAddedRawMeasure(MODULE_REF, RELIABILITY_RATING_KEY, E); + verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, E); + } + + @Test + public void compute_security_rating() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newVulnerabilityIssue(10L, MAJOR), newVulnerabilityIssue(1L, MAJOR), + // Should not be taken into account + newBugIssue(1L, MAJOR)); + fillComponentIssuesVisitorRule.setIssues(FILE_2_REF, newVulnerabilityIssue(2L, CRITICAL), newVulnerabilityIssue(3L, MINOR), + // Should not be taken into account + newVulnerabilityIssue(10L, BLOCKER).setResolution(RESOLUTION_FIXED)); + fillComponentIssuesVisitorRule.setIssues(MODULE_REF, newVulnerabilityIssue(7L, BLOCKER)); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(FILE_1_REF, SECURITY_RATING_KEY, C); + verifyAddedRawMeasure(FILE_2_REF, SECURITY_RATING_KEY, D); + verifyAddedRawMeasure(DIRECTORY_REF, SECURITY_RATING_KEY, D); + verifyAddedRawMeasure(MODULE_REF, SECURITY_RATING_KEY, E); + verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, E); + } + + @Test + public void compute_E_reliability_and_security_rating_on_blocker_issue() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, BLOCKER), newVulnerabilityIssue(1L, BLOCKER), + // Should not be taken into account + newBugIssue(1L, MAJOR)); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, E); + verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, E); + } + + @Test + public void compute_D_reliability_and_security_rating_on_critical_issue() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, CRITICAL), newVulnerabilityIssue(15L, CRITICAL), + // Should not be taken into account + newCodeSmellIssue(1L, MAJOR)); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, D); + verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, D); + } + + @Test + public void compute_C_reliability_and_security_rating_on_major_issue() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, MAJOR), newVulnerabilityIssue(15L, MAJOR), + // Should not be taken into account + newCodeSmellIssue(1L, MAJOR)); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, C); + verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, C); + } + + @Test + public void compute_B_reliability_and_security_rating_on_minor_issue() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, MINOR), newVulnerabilityIssue(15L, MINOR), + // Should not be taken into account + newCodeSmellIssue(1L, MAJOR)); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, B); + verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, B); + } + + @Test + public void compute_A_reliability_and_security_rating_on_info_issue() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, INFO), newVulnerabilityIssue(15L, INFO), + // Should not be taken into account + newCodeSmellIssue(1L, MAJOR)); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, A); + verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, A); + } + + private void verifyAddedRawMeasure(int componentRef, String metricKey, Rating rating) { + assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(rating.getIndex(), rating.name()))); + } + + private static Measure createRatingMeasure(Rating rating) { + return newMeasureBuilder().create(rating.getIndex(), rating.name()); + } + + private static DefaultIssue newBugIssue(long effort, String severity) { + return newIssue(effort, severity, BUG); + } + + private static DefaultIssue newVulnerabilityIssue(long effort, String severity) { + return newIssue(effort, severity, VULNERABILITY); + } + + private static DefaultIssue newCodeSmellIssue(long effort, String severity) { + return newIssue(effort, severity, CODE_SMELL); + } + + private static DefaultIssue newIssue(long effort, String severity, RuleType type) { + return newIssue(severity, type) + .setEffort(Duration.create(effort)); + } + + private static DefaultIssue newIssue(String severity, RuleType type) { + return new DefaultIssue() + .setKey(Uuids.create()) + .setSeverity(severity) + .setType(type) + .setCreationDate(new Date(1000l)); + } + +} -- cgit v1.2.3