From: Eric Giffon Date: Tue, 27 Aug 2024 11:40:14 +0000 (+0200) Subject: SONAR-22874 Rename Measure classes to ProjectMeasure X-Git-Tag: 10.7.0.96327~151 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=d8ebc8fbb62dad04ed4f665379bd80c4d7d88dc2;p=sonarqube.git SONAR-22874 Rename Measure classes to ProjectMeasure --- diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/measure/MeasureRepositoryImplIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/measure/MeasureRepositoryImplIT.java index b030f2474b1..30484ebcca7 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/measure/MeasureRepositoryImplIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/measure/MeasureRepositoryImplIT.java @@ -46,7 +46,7 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.metric.MetricDto; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Measure.StringValue; @@ -144,8 +144,8 @@ public class MeasureRepositoryImplIT { SnapshotDto oldAnalysis = dbTester.components().insertSnapshot(project, t -> t.setLast(false)); MetricDto metric1 = dbTester.measures().insertMetric(t -> t.setValueType(org.sonar.api.measures.Metric.ValueType.STRING.name())); MetricDto metric2 = dbTester.measures().insertMetric(t -> t.setValueType(org.sonar.api.measures.Metric.ValueType.STRING.name())); - dbClient.measureDao().insert(dbSession, createMeasureDto(metric1.getUuid(), FILE_COMPONENT.getUuid(), lastAnalysis.getUuid())); - dbClient.measureDao().insert(dbSession, createMeasureDto(metric1.getUuid(), FILE_COMPONENT.getUuid(), oldAnalysis.getUuid())); + dbClient.projectMeasureDao().insert(dbSession, createMeasureDto(metric1.getUuid(), FILE_COMPONENT.getUuid(), lastAnalysis.getUuid())); + dbClient.projectMeasureDao().insert(dbSession, createMeasureDto(metric1.getUuid(), FILE_COMPONENT.getUuid(), oldAnalysis.getUuid())); dbSession.commit(); // metric 1 is associated to snapshot with "last=true" @@ -398,8 +398,8 @@ public class MeasureRepositoryImplIT { assertThat(rawMeasures.get(METRIC_KEY_2)).extracting(Measure::getStringValue).isEqualTo("some value"); } - private static MeasureDto createMeasureDto(String metricUuid, String componentUuid, String analysisUuid) { - return new MeasureDto() + private static ProjectMeasureDto createMeasureDto(String metricUuid, String componentUuid, String analysisUuid) { + return new ProjectMeasureDto() .setComponentUuid(componentUuid) .setAnalysisUuid(analysisUuid) .setData(SOME_DATA) diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStepIT.java deleted file mode 100644 index 3b855a3be86..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStepIT.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.ce.task.projectanalysis.step; - -import java.util.Optional; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.measures.Metric; -import org.sonar.api.utils.System2; -import org.sonar.ce.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule; -import org.sonar.ce.task.projectanalysis.component.Component; -import org.sonar.ce.task.projectanalysis.component.ReportComponent; -import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; -import org.sonar.ce.task.projectanalysis.component.ViewsComponent; -import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule; -import org.sonar.ce.task.projectanalysis.measure.MeasureToMeasureDto; -import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.ce.task.step.ComputationStep; -import org.sonar.ce.task.step.TestComputationStepContext; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.measure.MeasureDto; -import org.sonar.db.metric.MetricDto; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY; -import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE; -import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT; -import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT_VIEW; -import static org.sonar.ce.task.projectanalysis.component.Component.Type.SUBVIEW; -import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW; -import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder; - -public class PersistMeasuresStepIT extends BaseStepTest { - - private static final Metric STRING_METRIC = new Metric.Builder("string-metric", "String metric", Metric.ValueType.STRING).create(); - private static final Metric INT_METRIC = new Metric.Builder("int-metric", "int metric", Metric.ValueType.INT).create(); - private static final Metric NON_HISTORICAL_METRIC = new Metric.Builder("nh-metric", "nh metric", Metric.ValueType.INT).setDeleteHistoricalData(true).create(); - - private static final String ANALYSIS_UUID = "a1"; - - private static final int REF_1 = 1; - private static final int REF_2 = 2; - private static final int REF_3 = 3; - private static final int REF_4 = 4; - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); - @Rule - public MetricRepositoryRule metricRepository = new MetricRepositoryRule(); - @Rule - public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - @Rule - public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule(); - - private DbClient dbClient = db.getDbClient(); - - @Before - public void setUp() { - analysisMetadataHolder.setUuid(ANALYSIS_UUID); - MetricDto stringMetricDto = db.measures().insertMetric(m -> m.setKey(STRING_METRIC.getKey()).setValueType(Metric.ValueType.STRING.name())); - MetricDto intMetricDto = db.measures().insertMetric(m -> m.setKey(INT_METRIC.getKey()).setValueType(Metric.ValueType.INT.name())); - MetricDto nhMetricDto = db.measures().insertMetric(m -> m.setKey(NON_HISTORICAL_METRIC.getKey()).setValueType(Metric.ValueType.INT.name())); - metricRepository.add(stringMetricDto.getUuid(), STRING_METRIC); - metricRepository.add(intMetricDto.getUuid(), INT_METRIC); - metricRepository.add(nhMetricDto.getUuid(), NON_HISTORICAL_METRIC); - } - - @Test - public void measures_on_non_historical_metrics_are_not_persisted() { - prepareProject(); - measureRepository.addRawMeasure(REF_1, NON_HISTORICAL_METRIC.getKey(), newMeasureBuilder().create(1)); - measureRepository.addRawMeasure(REF_1, INT_METRIC.getKey(), newMeasureBuilder().create(2)); - - TestComputationStepContext context = execute(); - - assertThatMeasureIsNotPersisted("project-uuid", NON_HISTORICAL_METRIC); - MeasureDto persistedMeasure = selectMeasure("project-uuid", INT_METRIC).get(); - assertThat(persistedMeasure.getValue()).isEqualTo(2); - assertNbOfInserts(context, 1); - } - - @Test - public void persist_measures_of_project_analysis_excluding_directories() { - prepareProject(); - - // the computed measures - measureRepository.addRawMeasure(REF_1, STRING_METRIC.getKey(), newMeasureBuilder().create("project-value")); - measureRepository.addRawMeasure(REF_3, STRING_METRIC.getKey(), newMeasureBuilder().create("dir-value")); - measureRepository.addRawMeasure(REF_4, STRING_METRIC.getKey(), newMeasureBuilder().create("file-value")); - - TestComputationStepContext context = execute(); - - // project and dir measures are persisted, but not file measures - assertThat(db.countRowsOfTable("project_measures")).isOne(); - assertThat(selectMeasure("project-uuid", STRING_METRIC).get().getData()).isEqualTo("project-value"); - assertThatMeasuresAreNotPersisted("dir-uuid"); - assertThatMeasuresAreNotPersisted("file-uuid"); - assertNbOfInserts(context, 1); - } - - @Test - public void measures_without_value_are_not_persisted() { - prepareProject(); - measureRepository.addRawMeasure(REF_1, STRING_METRIC.getKey(), newMeasureBuilder().createNoValue()); - measureRepository.addRawMeasure(REF_1, INT_METRIC.getKey(), newMeasureBuilder().createNoValue()); - - TestComputationStepContext context = execute(); - - assertThatMeasureIsNotPersisted("project-uuid", STRING_METRIC); - assertThatMeasureIsNotPersisted("project-uuid", INT_METRIC); - assertNbOfInserts(context, 0); - } - - @Test - public void measures_on_new_code_period_are_persisted() { - prepareProject(); - measureRepository.addRawMeasure(REF_1, INT_METRIC.getKey(), newMeasureBuilder().create(42.0)); - - TestComputationStepContext context = execute(); - - MeasureDto persistedMeasure = selectMeasure("project-uuid", INT_METRIC).get(); - assertThat(persistedMeasure.getValue()).isEqualTo(42.0); - assertNbOfInserts(context, 1); - } - - @Test - public void persist_all_measures_of_portfolio_analysis() { - preparePortfolio(); - - // the computed measures - measureRepository.addRawMeasure(REF_1, STRING_METRIC.getKey(), newMeasureBuilder().create("view-value")); - measureRepository.addRawMeasure(REF_2, STRING_METRIC.getKey(), newMeasureBuilder().create("subview-value")); - measureRepository.addRawMeasure(REF_3, STRING_METRIC.getKey(), newMeasureBuilder().create("project-value")); - - TestComputationStepContext context = execute(); - - assertThat(db.countRowsOfTable("project_measures")).isEqualTo(2); - assertThat(selectMeasure("view-uuid", STRING_METRIC).get().getData()).isEqualTo("view-value"); - assertThat(selectMeasure("subview-uuid", STRING_METRIC).get().getData()).isEqualTo("subview-value"); - assertNbOfInserts(context, 2); - } - - private void prepareProject() { - // tree of components as defined by scanner report - Component project = ReportComponent.builder(PROJECT, REF_1).setUuid("project-uuid") - .addChildren( - ReportComponent.builder(DIRECTORY, REF_3).setUuid("dir-uuid") - .addChildren( - ReportComponent.builder(FILE, REF_4).setUuid("file-uuid") - .build()) - .build()) - .build(); - treeRootHolder.setRoot(project); - - // components as persisted in db - ComponentDto projectDto = insertComponent("project-key", "project-uuid"); - ComponentDto dirDto = insertComponent("dir-key", "dir-uuid"); - ComponentDto fileDto = insertComponent("file-key", "file-uuid"); - db.components().insertSnapshot(projectDto, s -> s.setUuid(ANALYSIS_UUID)); - } - - private void preparePortfolio() { - // tree of components - Component portfolio = ViewsComponent.builder(VIEW, REF_1).setUuid("view-uuid") - .addChildren( - ViewsComponent.builder(SUBVIEW, REF_2).setUuid("subview-uuid") - .addChildren( - ViewsComponent.builder(PROJECT_VIEW, REF_3).setUuid("project-uuid") - .build()) - .build()) - .build(); - treeRootHolder.setRoot(portfolio); - - // components as persisted in db - ComponentDto viewDto = insertComponent("view-key", "view-uuid"); - ComponentDto subViewDto = insertComponent("subview-key", "subview-uuid"); - ComponentDto projectDto = insertComponent("project-key", "project-uuid"); - db.components().insertSnapshot(viewDto, s -> s.setUuid(ANALYSIS_UUID)); - } - - private void assertThatMeasureIsNotPersisted(String componentUuid, Metric metric) { - assertThat(selectMeasure(componentUuid, metric)).isEmpty(); - } - - private void assertThatMeasuresAreNotPersisted(String componentUuid) { - assertThatMeasureIsNotPersisted(componentUuid, STRING_METRIC); - assertThatMeasureIsNotPersisted(componentUuid, INT_METRIC); - } - - private TestComputationStepContext execute() { - TestComputationStepContext context = new TestComputationStepContext(); - new PersistMeasuresStep(dbClient, metricRepository, new MeasureToMeasureDto(analysisMetadataHolder, treeRootHolder), treeRootHolder, measureRepository) - .execute(context); - return context; - } - - private Optional selectMeasure(String componentUuid, Metric metric) { - return dbClient.measureDao().selectMeasure(db.getSession(), ANALYSIS_UUID, componentUuid, metric.getKey()); - } - - private ComponentDto insertComponent(String key, String uuid) { - ComponentDto componentDto = new ComponentDto() - .setKey(key) - .setUuid(uuid) - .setUuidPath(uuid + ".") - .setBranchUuid(uuid); - db.components().insertComponent(componentDto); - return componentDto; - } - - private static void assertNbOfInserts(TestComputationStepContext context, int expected) { - context.getStatistics().assertValue("inserts", expected); - } - - @Override - protected ComputationStep step() { - return new PersistMeasuresStep(dbClient, metricRepository, new MeasureToMeasureDto(analysisMetadataHolder, treeRootHolder), treeRootHolder, measureRepository); - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistProjectMeasuresStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistProjectMeasuresStepIT.java new file mode 100644 index 00000000000..94f98923ae7 --- /dev/null +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistProjectMeasuresStepIT.java @@ -0,0 +1,241 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.ce.task.projectanalysis.step; + +import java.util.Optional; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.measures.Metric; +import org.sonar.api.utils.System2; +import org.sonar.ce.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule; +import org.sonar.ce.task.projectanalysis.component.Component; +import org.sonar.ce.task.projectanalysis.component.ReportComponent; +import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; +import org.sonar.ce.task.projectanalysis.component.ViewsComponent; +import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule; +import org.sonar.ce.task.projectanalysis.measure.MeasureToMeasureDto; +import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule; +import org.sonar.ce.task.step.ComputationStep; +import org.sonar.ce.task.step.TestComputationStepContext; +import org.sonar.db.DbClient; +import org.sonar.db.DbTester; +import org.sonar.db.component.ComponentDto; +import org.sonar.db.measure.ProjectMeasureDto; +import org.sonar.db.metric.MetricDto; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY; +import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE; +import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT; +import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT_VIEW; +import static org.sonar.ce.task.projectanalysis.component.Component.Type.SUBVIEW; +import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW; +import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder; + +public class PersistProjectMeasuresStepIT extends BaseStepTest { + + private static final Metric STRING_METRIC = new Metric.Builder("string-metric", "String metric", Metric.ValueType.STRING).create(); + private static final Metric INT_METRIC = new Metric.Builder("int-metric", "int metric", Metric.ValueType.INT).create(); + private static final Metric NON_HISTORICAL_METRIC = new Metric.Builder("nh-metric", "nh metric", Metric.ValueType.INT).setDeleteHistoricalData(true).create(); + + private static final String ANALYSIS_UUID = "a1"; + + private static final int REF_1 = 1; + private static final int REF_2 = 2; + private static final int REF_3 = 3; + private static final int REF_4 = 4; + + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); + @Rule + public MetricRepositoryRule metricRepository = new MetricRepositoryRule(); + @Rule + public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); + @Rule + public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule(); + + private DbClient dbClient = db.getDbClient(); + + @Before + public void setUp() { + analysisMetadataHolder.setUuid(ANALYSIS_UUID); + MetricDto stringMetricDto = db.measures().insertMetric(m -> m.setKey(STRING_METRIC.getKey()).setValueType(Metric.ValueType.STRING.name())); + MetricDto intMetricDto = db.measures().insertMetric(m -> m.setKey(INT_METRIC.getKey()).setValueType(Metric.ValueType.INT.name())); + MetricDto nhMetricDto = db.measures().insertMetric(m -> m.setKey(NON_HISTORICAL_METRIC.getKey()).setValueType(Metric.ValueType.INT.name())); + metricRepository.add(stringMetricDto.getUuid(), STRING_METRIC); + metricRepository.add(intMetricDto.getUuid(), INT_METRIC); + metricRepository.add(nhMetricDto.getUuid(), NON_HISTORICAL_METRIC); + } + + @Test + public void measures_on_non_historical_metrics_are_not_persisted() { + prepareProject(); + measureRepository.addRawMeasure(REF_1, NON_HISTORICAL_METRIC.getKey(), newMeasureBuilder().create(1)); + measureRepository.addRawMeasure(REF_1, INT_METRIC.getKey(), newMeasureBuilder().create(2)); + + TestComputationStepContext context = execute(); + + assertThatMeasureIsNotPersisted("project-uuid", NON_HISTORICAL_METRIC); + ProjectMeasureDto persistedMeasure = selectMeasure("project-uuid", INT_METRIC).get(); + assertThat(persistedMeasure.getValue()).isEqualTo(2); + assertNbOfInserts(context, 1); + } + + @Test + public void persist_measures_of_project_analysis_excluding_directories() { + prepareProject(); + + // the computed measures + measureRepository.addRawMeasure(REF_1, STRING_METRIC.getKey(), newMeasureBuilder().create("project-value")); + measureRepository.addRawMeasure(REF_3, STRING_METRIC.getKey(), newMeasureBuilder().create("dir-value")); + measureRepository.addRawMeasure(REF_4, STRING_METRIC.getKey(), newMeasureBuilder().create("file-value")); + + TestComputationStepContext context = execute(); + + // project and dir measures are persisted, but not file measures + assertThat(db.countRowsOfTable("project_measures")).isOne(); + assertThat(selectMeasure("project-uuid", STRING_METRIC).get().getData()).isEqualTo("project-value"); + assertThatMeasuresAreNotPersisted("dir-uuid"); + assertThatMeasuresAreNotPersisted("file-uuid"); + assertNbOfInserts(context, 1); + } + + @Test + public void measures_without_value_are_not_persisted() { + prepareProject(); + measureRepository.addRawMeasure(REF_1, STRING_METRIC.getKey(), newMeasureBuilder().createNoValue()); + measureRepository.addRawMeasure(REF_1, INT_METRIC.getKey(), newMeasureBuilder().createNoValue()); + + TestComputationStepContext context = execute(); + + assertThatMeasureIsNotPersisted("project-uuid", STRING_METRIC); + assertThatMeasureIsNotPersisted("project-uuid", INT_METRIC); + assertNbOfInserts(context, 0); + } + + @Test + public void measures_on_new_code_period_are_persisted() { + prepareProject(); + measureRepository.addRawMeasure(REF_1, INT_METRIC.getKey(), newMeasureBuilder().create(42.0)); + + TestComputationStepContext context = execute(); + + ProjectMeasureDto persistedMeasure = selectMeasure("project-uuid", INT_METRIC).get(); + assertThat(persistedMeasure.getValue()).isEqualTo(42.0); + assertNbOfInserts(context, 1); + } + + @Test + public void persist_all_measures_of_portfolio_analysis() { + preparePortfolio(); + + // the computed measures + measureRepository.addRawMeasure(REF_1, STRING_METRIC.getKey(), newMeasureBuilder().create("view-value")); + measureRepository.addRawMeasure(REF_2, STRING_METRIC.getKey(), newMeasureBuilder().create("subview-value")); + measureRepository.addRawMeasure(REF_3, STRING_METRIC.getKey(), newMeasureBuilder().create("project-value")); + + TestComputationStepContext context = execute(); + + assertThat(db.countRowsOfTable("project_measures")).isEqualTo(2); + assertThat(selectMeasure("view-uuid", STRING_METRIC).get().getData()).isEqualTo("view-value"); + assertThat(selectMeasure("subview-uuid", STRING_METRIC).get().getData()).isEqualTo("subview-value"); + assertNbOfInserts(context, 2); + } + + private void prepareProject() { + // tree of components as defined by scanner report + Component project = ReportComponent.builder(PROJECT, REF_1).setUuid("project-uuid") + .addChildren( + ReportComponent.builder(DIRECTORY, REF_3).setUuid("dir-uuid") + .addChildren( + ReportComponent.builder(FILE, REF_4).setUuid("file-uuid") + .build()) + .build()) + .build(); + treeRootHolder.setRoot(project); + + // components as persisted in db + ComponentDto projectDto = insertComponent("project-key", "project-uuid"); + ComponentDto dirDto = insertComponent("dir-key", "dir-uuid"); + ComponentDto fileDto = insertComponent("file-key", "file-uuid"); + db.components().insertSnapshot(projectDto, s -> s.setUuid(ANALYSIS_UUID)); + } + + private void preparePortfolio() { + // tree of components + Component portfolio = ViewsComponent.builder(VIEW, REF_1).setUuid("view-uuid") + .addChildren( + ViewsComponent.builder(SUBVIEW, REF_2).setUuid("subview-uuid") + .addChildren( + ViewsComponent.builder(PROJECT_VIEW, REF_3).setUuid("project-uuid") + .build()) + .build()) + .build(); + treeRootHolder.setRoot(portfolio); + + // components as persisted in db + ComponentDto viewDto = insertComponent("view-key", "view-uuid"); + ComponentDto subViewDto = insertComponent("subview-key", "subview-uuid"); + ComponentDto projectDto = insertComponent("project-key", "project-uuid"); + db.components().insertSnapshot(viewDto, s -> s.setUuid(ANALYSIS_UUID)); + } + + private void assertThatMeasureIsNotPersisted(String componentUuid, Metric metric) { + assertThat(selectMeasure(componentUuid, metric)).isEmpty(); + } + + private void assertThatMeasuresAreNotPersisted(String componentUuid) { + assertThatMeasureIsNotPersisted(componentUuid, STRING_METRIC); + assertThatMeasureIsNotPersisted(componentUuid, INT_METRIC); + } + + private TestComputationStepContext execute() { + TestComputationStepContext context = new TestComputationStepContext(); + new PersistProjectMeasuresStep(dbClient, metricRepository, new MeasureToMeasureDto(analysisMetadataHolder, treeRootHolder), treeRootHolder, measureRepository) + .execute(context); + return context; + } + + private Optional selectMeasure(String componentUuid, Metric metric) { + return dbClient.projectMeasureDao().selectMeasure(db.getSession(), ANALYSIS_UUID, componentUuid, metric.getKey()); + } + + private ComponentDto insertComponent(String key, String uuid) { + ComponentDto componentDto = new ComponentDto() + .setKey(key) + .setUuid(uuid) + .setUuidPath(uuid + ".") + .setBranchUuid(uuid); + db.components().insertComponent(componentDto); + return componentDto; + } + + private static void assertNbOfInserts(TestComputationStepContext context, int expected) { + context.getStatistics().assertValue("inserts", expected); + } + + @Override + protected ComputationStep step() { + return new PersistProjectMeasuresStep(dbClient, metricRepository, new MeasureToMeasureDto(analysisMetadataHolder, treeRootHolder), treeRootHolder, measureRepository); + } +} diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/steps/ExportMeasuresStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/steps/ExportMeasuresStepIT.java index 4c0182de2a7..86088a37c01 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/steps/ExportMeasuresStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/steps/ExportMeasuresStepIT.java @@ -34,7 +34,7 @@ import org.sonar.db.component.BranchDto; import org.sonar.db.component.BranchType; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.metric.MetricDto; import static com.google.common.collect.Lists.newArrayList; @@ -129,11 +129,11 @@ public class ExportMeasuresStepIT { @Test public void export_measures() { SnapshotDto firstAnalysis = insertSnapshot("U_1", PROJECT, STATUS_PROCESSED); - insertMeasure(firstAnalysis, PROJECT, new MeasureDto().setValue(100.0).setMetricUuid(NCLOC.getUuid())); + insertMeasure(firstAnalysis, PROJECT, new ProjectMeasureDto().setValue(100.0).setMetricUuid(NCLOC.getUuid())); SnapshotDto secondAnalysis = insertSnapshot("U_2", PROJECT, STATUS_PROCESSED); - insertMeasure(secondAnalysis, PROJECT, new MeasureDto().setValue(110.0).setMetricUuid(NCLOC.getUuid())); + insertMeasure(secondAnalysis, PROJECT, new ProjectMeasureDto().setValue(110.0).setMetricUuid(NCLOC.getUuid())); SnapshotDto anotherProjectAnalysis = insertSnapshot("U_3", ANOTHER_PROJECT, STATUS_PROCESSED); - insertMeasure(anotherProjectAnalysis, ANOTHER_PROJECT, new MeasureDto().setValue(500.0).setMetricUuid(NCLOC.getUuid())); + insertMeasure(anotherProjectAnalysis, ANOTHER_PROJECT, new ProjectMeasureDto().setValue(500.0).setMetricUuid(NCLOC.getUuid())); dbTester.commit(); underTest.execute(new TestComputationStepContext()); @@ -149,7 +149,7 @@ public class ExportMeasuresStepIT { @Test public void do_not_export_measures_on_unprocessed_snapshots() { SnapshotDto firstAnalysis = insertSnapshot("U_1", PROJECT, STATUS_UNPROCESSED); - insertMeasure(firstAnalysis, PROJECT, new MeasureDto().setValue(100.0).setMetricUuid(NCLOC.getUuid())); + insertMeasure(firstAnalysis, PROJECT, new ProjectMeasureDto().setValue(100.0).setMetricUuid(NCLOC.getUuid())); dbTester.commit(); underTest.execute(new TestComputationStepContext()); @@ -161,7 +161,7 @@ public class ExportMeasuresStepIT { @Test public void do_not_export_measures_on_disabled_metrics() { SnapshotDto firstAnalysis = insertSnapshot("U_1", PROJECT, STATUS_PROCESSED); - insertMeasure(firstAnalysis, PROJECT, new MeasureDto().setValue(100.0).setMetricUuid(DISABLED_METRIC.getUuid())); + insertMeasure(firstAnalysis, PROJECT, new ProjectMeasureDto().setValue(100.0).setMetricUuid(DISABLED_METRIC.getUuid())); dbTester.commit(); underTest.execute(new TestComputationStepContext()); @@ -173,7 +173,7 @@ public class ExportMeasuresStepIT { @Test public void test_exported_fields() { SnapshotDto analysis = insertSnapshot("U_1", PROJECT, STATUS_PROCESSED); - MeasureDto dto = new MeasureDto() + ProjectMeasureDto dto = new ProjectMeasureDto() .setMetricUuid(NCLOC.getUuid()) .setValue(100.0) .setData("data") @@ -198,7 +198,7 @@ public class ExportMeasuresStepIT { @Test public void test_exported_fields_new_metric() { SnapshotDto analysis = insertSnapshot("U_1", PROJECT, STATUS_PROCESSED); - MeasureDto dto = new MeasureDto() + ProjectMeasureDto dto = new ProjectMeasureDto() .setMetricUuid(NEW_NCLOC.getUuid()) .setValue(100.0) .setData("data") @@ -223,7 +223,7 @@ public class ExportMeasuresStepIT { @Test public void test_null_exported_fields() { SnapshotDto analysis = insertSnapshot("U_1", PROJECT, STATUS_PROCESSED); - insertMeasure(analysis, PROJECT, new MeasureDto().setMetricUuid(NCLOC.getUuid())); + insertMeasure(analysis, PROJECT, new ProjectMeasureDto().setMetricUuid(NCLOC.getUuid())); dbTester.commit(); underTest.execute(new TestComputationStepContext()); @@ -251,10 +251,10 @@ public class ExportMeasuresStepIT { return snapshot; } - private void insertMeasure(SnapshotDto analysisDto, ComponentDto componentDto, MeasureDto measureDto) { - measureDto + private void insertMeasure(SnapshotDto analysisDto, ComponentDto componentDto, ProjectMeasureDto projectMeasureDto) { + projectMeasureDto .setAnalysisUuid(analysisDto.getUuid()) .setComponentUuid(componentDto.uuid()); - dbTester.getDbClient().measureDao().insert(dbTester.getSession(), measureDto); + dbTester.getDbClient().projectMeasureDao().insert(dbTester.getSession(), projectMeasureDto); } } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/BatchMeasureToMeasure.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/BatchMeasureToMeasure.java index ded09f27e62..b5b35a45eec 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/BatchMeasureToMeasure.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/BatchMeasureToMeasure.java @@ -31,7 +31,11 @@ import static org.apache.commons.lang3.StringUtils.trimToNull; public class BatchMeasureToMeasure { - public Optional toMeasure(@Nullable ScannerReport.Measure batchMeasure, Metric metric) { + private BatchMeasureToMeasure() { + // utility class + } + + public static Optional toMeasure(@Nullable ScannerReport.Measure batchMeasure, Metric metric) { Objects.requireNonNull(metric); if (batchMeasure == null) { return Optional.empty(); diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/LiveMeasureDtoToMeasure.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/LiveMeasureDtoToMeasure.java index e9873db208d..1c0e3eedaac 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/LiveMeasureDtoToMeasure.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/LiveMeasureDtoToMeasure.java @@ -30,7 +30,11 @@ import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.toLevel; public class LiveMeasureDtoToMeasure { - public Optional toMeasure(@Nullable LiveMeasureDto measureDto, Metric metric) { + private LiveMeasureDtoToMeasure() { + // utility class + } + + public static Optional toMeasure(@Nullable LiveMeasureDto measureDto, Metric metric) { requireNonNull(metric); if (measureDto == null) { return Optional.empty(); diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureDtoToMeasure.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureDtoToMeasure.java deleted file mode 100644 index a0edc84c61d..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureDtoToMeasure.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.ce.task.projectanalysis.measure; - -import java.util.Optional; -import javax.annotation.Nullable; -import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.db.measure.MeasureDto; - -import static java.util.Objects.requireNonNull; -import static java.util.Optional.of; -import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.toLevel; - -public class MeasureDtoToMeasure { - - public Optional toMeasure(@Nullable MeasureDto measureDto, Metric metric) { - requireNonNull(metric); - if (measureDto == null) { - return Optional.empty(); - } - Double value = measureDto.getValue(); - String data = measureDto.getData(); - switch (metric.getType().getValueType()) { - case INT: - return toIntegerMeasure(measureDto, value, data); - case LONG: - return toLongMeasure(measureDto, value, data); - case DOUBLE: - return toDoubleMeasure(measureDto, value, data); - case BOOLEAN: - return toBooleanMeasure(measureDto, value, data); - case STRING: - return toStringMeasure(measureDto, data); - case LEVEL: - return toLevelMeasure(measureDto, data); - case NO_VALUE: - return toNoValueMeasure(measureDto); - default: - throw new IllegalArgumentException("Unsupported Measure.ValueType " + metric.getType().getValueType()); - } - } - - private static Optional toIntegerMeasure(MeasureDto measureDto, @Nullable Double value, String data) { - if (value == null) { - return toNoValueMeasure(measureDto); - } - return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(value.intValue(), data)); - } - - private static Optional toLongMeasure(MeasureDto measureDto, @Nullable Double value, String data) { - if (value == null) { - return toNoValueMeasure(measureDto); - } - return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(value.longValue(), data)); - } - - private static Optional toDoubleMeasure(MeasureDto measureDto, @Nullable Double value, String data) { - if (value == null) { - return toNoValueMeasure(measureDto); - } - - return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto) - .create(value, org.sonar.api.measures.Metric.MAX_DECIMAL_SCALE, data)); - } - - private static Optional toBooleanMeasure(MeasureDto measureDto, @Nullable Double value, String data) { - if (value == null) { - return toNoValueMeasure(measureDto); - } - return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(Double.compare(value, 1.0D) == 0, data)); - } - - private static Optional toStringMeasure(MeasureDto measureDto, @Nullable String data) { - if (data == null) { - return toNoValueMeasure(measureDto); - } - return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(data)); - } - - private static Optional toLevelMeasure(MeasureDto measureDto, @Nullable String data) { - if (data == null) { - return toNoValueMeasure(measureDto); - } - Optional level = toLevel(data); - if (!level.isPresent()) { - return toNoValueMeasure(measureDto); - } - return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(level.get())); - } - - private static Optional toNoValueMeasure(MeasureDto measureDto) { - return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).createNoValue()); - } - - private static Measure.NewMeasureBuilder setCommonProperties(Measure.NewMeasureBuilder builder, MeasureDto measureDto) { - if (measureDto.getAlertStatus() != null) { - Optional qualityGateStatus = toLevel(measureDto.getAlertStatus()); - if (qualityGateStatus.isPresent()) { - builder.setQualityGateStatus(new QualityGateStatus(qualityGateStatus.get(), measureDto.getAlertText())); - } - } - return builder; - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureRepositoryImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureRepositoryImpl.java index 27b334da69c..9abcb5c6d2c 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureRepositoryImpl.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureRepositoryImpl.java @@ -32,7 +32,7 @@ import org.sonar.ce.task.projectanalysis.metric.ReportMetricValidator; import org.sonar.core.util.CloseableIterator; import org.sonar.db.DbClient; import org.sonar.db.DbSession; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.scanner.protocol.output.ScannerReport; import static java.util.Objects.requireNonNull; @@ -42,11 +42,9 @@ public class MeasureRepositoryImpl implements MeasureRepository { private final MapBasedRawMeasureRepository delegate = new MapBasedRawMeasureRepository<>(toComponentUuid()); private final DbClient dbClient; private final BatchReportReader reportReader; - private final BatchMeasureToMeasure batchMeasureToMeasure; private final MetricRepository metricRepository; private final ReportMetricValidator reportMetricValidator; - private MeasureDtoToMeasure measureTransformer = new MeasureDtoToMeasure(); private final Set loadedComponents = new HashSet<>(); public MeasureRepositoryImpl(DbClient dbClient, BatchReportReader reportReader, MetricRepository metricRepository, @@ -54,7 +52,6 @@ public class MeasureRepositoryImpl implements MeasureRepository { this.dbClient = dbClient; this.reportReader = reportReader; this.reportMetricValidator = reportMetricValidator; - this.batchMeasureToMeasure = new BatchMeasureToMeasure(); this.metricRepository = metricRepository; } @@ -65,9 +62,9 @@ public class MeasureRepositoryImpl implements MeasureRepository { requireNonNull(metric); try (DbSession dbSession = dbClient.openSession(false)) { - Optional measureDto = dbClient.measureDao().selectLastMeasure(dbSession, component.getUuid(), metric.getKey()); + Optional measureDto = dbClient.projectMeasureDao().selectLastMeasure(dbSession, component.getUuid(), metric.getKey()); if (measureDto.isPresent()) { - return measureTransformer.toMeasure(measureDto.get(), metric); + return ProjectMeasureDtoToMeasure.toMeasure(measureDto.get(), metric); } return Optional.empty(); } @@ -113,7 +110,7 @@ public class MeasureRepositoryImpl implements MeasureRepository { String metricKey = batchMeasure.getMetricKey(); if (reportMetricValidator.validate(metricKey)) { Metric metric = metricRepository.getByKey(metricKey); - batchMeasureToMeasure.toMeasure(batchMeasure, metric).ifPresent(measure -> delegate.add(component, metric, measure, OverridePolicy.DO_NOT_OVERRIDE)); + BatchMeasureToMeasure.toMeasure(batchMeasure, metric).ifPresent(measure -> delegate.add(component, metric, measure, OverridePolicy.DO_NOT_OVERRIDE)); } } } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureToMeasureDto.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureToMeasureDto.java index f013e2e6e5f..fcd4b2d4a4b 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureToMeasureDto.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/MeasureToMeasureDto.java @@ -23,7 +23,7 @@ import javax.annotation.CheckForNull; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.metric.Metric; import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.ce.task.projectanalysis.component.TreeRootHolder; @@ -37,8 +37,8 @@ public class MeasureToMeasureDto { this.treeRootHolder = treeRootHolder; } - public MeasureDto toMeasureDto(Measure measure, Metric metric, Component component) { - MeasureDto out = new MeasureDto(); + public ProjectMeasureDto toProjectMeasureDto(Measure measure, Metric metric, Component component) { + ProjectMeasureDto out = new ProjectMeasureDto(); out.setMetricUuid(metric.getUuid()); out.setComponentUuid(component.getUuid()); out.setAnalysisUuid(analysisMetadataHolder.getUuid()); @@ -60,9 +60,9 @@ public class MeasureToMeasureDto { return out; } - private static void setAlert(MeasureDto measureDto, QualityGateStatus qualityGateStatus) { - measureDto.setAlertStatus(qualityGateStatus.getStatus().name()); - measureDto.setAlertText(qualityGateStatus.getText()); + private static void setAlert(ProjectMeasureDto projectMeasureDto, QualityGateStatus qualityGateStatus) { + projectMeasureDto.setAlertStatus(qualityGateStatus.getStatus().name()); + projectMeasureDto.setAlertText(qualityGateStatus.getText()); } private static String data(Measure in) { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/ProjectMeasureDtoToMeasure.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/ProjectMeasureDtoToMeasure.java new file mode 100644 index 00000000000..215073ba8c6 --- /dev/null +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/ProjectMeasureDtoToMeasure.java @@ -0,0 +1,125 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.ce.task.projectanalysis.measure; + +import java.util.Optional; +import javax.annotation.Nullable; +import org.sonar.ce.task.projectanalysis.metric.Metric; +import org.sonar.db.measure.ProjectMeasureDto; + +import static java.util.Objects.requireNonNull; +import static java.util.Optional.of; +import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.toLevel; + +public class ProjectMeasureDtoToMeasure { + + private ProjectMeasureDtoToMeasure() { + // utility class + } + + public static Optional toMeasure(@Nullable ProjectMeasureDto measureDto, Metric metric) { + requireNonNull(metric); + if (measureDto == null) { + return Optional.empty(); + } + Double value = measureDto.getValue(); + String data = measureDto.getData(); + switch (metric.getType().getValueType()) { + case INT: + return toIntegerMeasure(measureDto, value, data); + case LONG: + return toLongMeasure(measureDto, value, data); + case DOUBLE: + return toDoubleMeasure(measureDto, value, data); + case BOOLEAN: + return toBooleanMeasure(measureDto, value, data); + case STRING: + return toStringMeasure(measureDto, data); + case LEVEL: + return toLevelMeasure(measureDto, data); + case NO_VALUE: + return toNoValueMeasure(measureDto); + default: + throw new IllegalArgumentException("Unsupported Measure.ValueType " + metric.getType().getValueType()); + } + } + + private static Optional toIntegerMeasure(ProjectMeasureDto measureDto, @Nullable Double value, @Nullable String data) { + if (value == null) { + return toNoValueMeasure(measureDto); + } + return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(value.intValue(), data)); + } + + private static Optional toLongMeasure(ProjectMeasureDto measureDto, @Nullable Double value, @Nullable String data) { + if (value == null) { + return toNoValueMeasure(measureDto); + } + return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(value.longValue(), data)); + } + + private static Optional toDoubleMeasure(ProjectMeasureDto measureDto, @Nullable Double value, @Nullable String data) { + if (value == null) { + return toNoValueMeasure(measureDto); + } + + return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto) + .create(value, org.sonar.api.measures.Metric.MAX_DECIMAL_SCALE, data)); + } + + private static Optional toBooleanMeasure(ProjectMeasureDto measureDto, @Nullable Double value, @Nullable String data) { + if (value == null) { + return toNoValueMeasure(measureDto); + } + return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(Double.compare(value, 1.0D) == 0, data)); + } + + private static Optional toStringMeasure(ProjectMeasureDto measureDto, @Nullable String data) { + if (data == null) { + return toNoValueMeasure(measureDto); + } + return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(data)); + } + + private static Optional toLevelMeasure(ProjectMeasureDto measureDto, @Nullable String data) { + if (data == null) { + return toNoValueMeasure(measureDto); + } + Optional level = toLevel(data); + if (!level.isPresent()) { + return toNoValueMeasure(measureDto); + } + return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(level.get())); + } + + private static Optional toNoValueMeasure(ProjectMeasureDto measureDto) { + return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).createNoValue()); + } + + private static Measure.NewMeasureBuilder setCommonProperties(Measure.NewMeasureBuilder builder, ProjectMeasureDto measureDto) { + if (measureDto.getAlertStatus() != null) { + Optional qualityGateStatus = toLevel(measureDto.getAlertStatus()); + if (qualityGateStatus.isPresent()) { + builder.setQualityGateStatus(new QualityGateStatus(qualityGateStatus.get(), measureDto.getAlertText())); + } + } + return builder; + } +} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStep.java deleted file mode 100644 index a981c1bc6fb..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStep.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.ce.task.projectanalysis.step; - -import java.util.Map; -import org.sonar.ce.task.projectanalysis.component.Component; -import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit; -import org.sonar.ce.task.projectanalysis.component.DepthTraversalTypeAwareCrawler; -import org.sonar.ce.task.projectanalysis.component.TreeRootHolder; -import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitorAdapter; -import org.sonar.ce.task.projectanalysis.measure.Measure; -import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; -import org.sonar.ce.task.projectanalysis.measure.MeasureToMeasureDto; -import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.ce.task.projectanalysis.metric.MetricRepository; -import org.sonar.ce.task.step.ComputationStep; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.measure.MeasureDao; -import org.sonar.db.measure.MeasureDto; - -import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER; - -public class PersistMeasuresStep implements ComputationStep { - - private final DbClient dbClient; - private final MetricRepository metricRepository; - private final MeasureToMeasureDto measureToMeasureDto; - private final TreeRootHolder treeRootHolder; - private final MeasureRepository measureRepository; - - public PersistMeasuresStep(DbClient dbClient, MetricRepository metricRepository, MeasureToMeasureDto measureToMeasureDto, TreeRootHolder treeRootHolder, - MeasureRepository measureRepository) { - this.dbClient = dbClient; - this.metricRepository = metricRepository; - this.measureToMeasureDto = measureToMeasureDto; - this.treeRootHolder = treeRootHolder; - this.measureRepository = measureRepository; - } - - @Override - public String getDescription() { - return "Persist measures"; - } - - @Override - public void execute(ComputationStep.Context context) { - try (DbSession dbSession = dbClient.openSession(true)) { - MeasureVisitor visitor = new MeasureVisitor(dbSession); - new DepthTraversalTypeAwareCrawler(visitor).visit(treeRootHolder.getRoot()); - dbSession.commit(); - context.getStatistics().add("inserts", visitor.inserts); - } - } - - private class MeasureVisitor extends TypeAwareVisitorAdapter { - private final DbSession session; - private int inserts = 0; - - private MeasureVisitor(DbSession session) { - super(CrawlerDepthLimit.LEAVES, PRE_ORDER); - this.session = session; - } - - @Override - public void visitProject(Component project) { - persistMeasures(project); - } - - @Override - public void visitView(Component view) { - persistMeasures(view); - } - - @Override - public void visitSubView(Component subView) { - persistMeasures(subView); - } - - @Override - public void visitProjectView(Component projectView) { - // measures of project copies are never read. No need to persist them. - } - - private void persistMeasures(Component component) { - Map measures = measureRepository.getRawMeasures(component); - MeasureDao measureDao = dbClient.measureDao(); - - for (Map.Entry e : measures.entrySet()) { - Measure measure = e.getValue(); - if (measure.isEmpty()) { - continue; - } - String metricKey = e.getKey(); - Metric metric = metricRepository.getByKey(metricKey); - if (!metric.isDeleteHistoricalData()) { - MeasureDto measureDto = measureToMeasureDto.toMeasureDto(measure, metric, component); - measureDao.insert(session, measureDto); - inserts++; - } - } - } - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistProjectMeasuresStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistProjectMeasuresStep.java new file mode 100644 index 00000000000..e713d0b59dd --- /dev/null +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistProjectMeasuresStep.java @@ -0,0 +1,121 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.ce.task.projectanalysis.step; + +import java.util.Map; +import org.sonar.ce.task.projectanalysis.component.Component; +import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit; +import org.sonar.ce.task.projectanalysis.component.DepthTraversalTypeAwareCrawler; +import org.sonar.ce.task.projectanalysis.component.TreeRootHolder; +import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitorAdapter; +import org.sonar.ce.task.projectanalysis.measure.Measure; +import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; +import org.sonar.ce.task.projectanalysis.measure.MeasureToMeasureDto; +import org.sonar.ce.task.projectanalysis.metric.Metric; +import org.sonar.ce.task.projectanalysis.metric.MetricRepository; +import org.sonar.ce.task.step.ComputationStep; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.measure.ProjectMeasureDao; +import org.sonar.db.measure.ProjectMeasureDto; + +import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER; + +public class PersistProjectMeasuresStep implements ComputationStep { + + private final DbClient dbClient; + private final MetricRepository metricRepository; + private final MeasureToMeasureDto measureToMeasureDto; + private final TreeRootHolder treeRootHolder; + private final MeasureRepository measureRepository; + + public PersistProjectMeasuresStep(DbClient dbClient, MetricRepository metricRepository, MeasureToMeasureDto measureToMeasureDto, TreeRootHolder treeRootHolder, + MeasureRepository measureRepository) { + this.dbClient = dbClient; + this.metricRepository = metricRepository; + this.measureToMeasureDto = measureToMeasureDto; + this.treeRootHolder = treeRootHolder; + this.measureRepository = measureRepository; + } + + @Override + public String getDescription() { + return "Persist project measures"; + } + + @Override + public void execute(ComputationStep.Context context) { + try (DbSession dbSession = dbClient.openSession(true)) { + MeasureVisitor visitor = new MeasureVisitor(dbSession); + new DepthTraversalTypeAwareCrawler(visitor).visit(treeRootHolder.getRoot()); + dbSession.commit(); + context.getStatistics().add("inserts", visitor.inserts); + } + } + + private class MeasureVisitor extends TypeAwareVisitorAdapter { + private final DbSession session; + private int inserts = 0; + + private MeasureVisitor(DbSession session) { + super(CrawlerDepthLimit.LEAVES, PRE_ORDER); + this.session = session; + } + + @Override + public void visitProject(Component project) { + persistMeasures(project); + } + + @Override + public void visitView(Component view) { + persistMeasures(view); + } + + @Override + public void visitSubView(Component subView) { + persistMeasures(subView); + } + + @Override + public void visitProjectView(Component projectView) { + // measures of project copies are never read. No need to persist them. + } + + private void persistMeasures(Component component) { + Map measures = measureRepository.getRawMeasures(component); + ProjectMeasureDao projectMeasureDao = dbClient.projectMeasureDao(); + + for (Map.Entry e : measures.entrySet()) { + Measure measure = e.getValue(); + if (measure.isEmpty()) { + continue; + } + String metricKey = e.getKey(); + Metric metric = metricRepository.getByKey(metricKey); + if (!metric.isDeleteHistoricalData()) { + ProjectMeasureDto projectMeasureDto = measureToMeasureDto.toProjectMeasureDto(measure, metric, component); + projectMeasureDao.insert(session, projectMeasureDto); + inserts++; + } + } + } + } +} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java index 6095afe8a71..9fbf27e0a35 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java @@ -105,7 +105,7 @@ public class ReportComputationSteps extends AbstractComputationSteps { PersistComponentsStep.class, PersistAnalysisStep.class, PersistAnalysisPropertiesStep.class, - PersistMeasuresStep.class, + PersistProjectMeasuresStep.class, PersistLiveMeasuresStep.class, PersistDuplicationDataStep.class, PersistAdHocRulesStep.class, diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/BatchMeasureToMeasureTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/BatchMeasureToMeasureTest.java index b1cdec26627..fa7d18321f4 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/BatchMeasureToMeasureTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/BatchMeasureToMeasureTest.java @@ -35,6 +35,7 @@ import org.sonar.scanner.protocol.output.ScannerReport.Measure.StringValue; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.sonar.ce.task.projectanalysis.measure.BatchMeasureToMeasure.*; @RunWith(DataProviderRunner.class) public class BatchMeasureToMeasureTest { @@ -48,28 +49,26 @@ public class BatchMeasureToMeasureTest { private static final String SOME_DATA = "some_data man!"; private static final ScannerReport.Measure EMPTY_BATCH_MEASURE = ScannerReport.Measure.newBuilder().build(); - private BatchMeasureToMeasure underTest = new BatchMeasureToMeasure(); - @Test public void toMeasure_returns_absent_for_null_argument() { - assertThat(underTest.toMeasure(null, SOME_INT_METRIC)).isNotPresent(); + assertThat(toMeasure(null, SOME_INT_METRIC)).isNotPresent(); } @Test public void toMeasure_throws_NPE_if_metric_argument_is_null() { - assertThatThrownBy(() -> underTest.toMeasure(EMPTY_BATCH_MEASURE, null)) + assertThatThrownBy(() -> toMeasure(EMPTY_BATCH_MEASURE, null)) .isInstanceOf(NullPointerException.class); } @Test public void toMeasure_throws_NPE_if_both_arguments_are_null() { - assertThatThrownBy(() -> underTest.toMeasure(null, null)) + assertThatThrownBy(() -> toMeasure(null, null)) .isInstanceOf(NullPointerException.class); } @Test public void toMeasure_returns_no_value_if_dto_has_no_string_value_for_LEVEL_Metric() { - Optional measure = underTest.toMeasure(EMPTY_BATCH_MEASURE, SOME_LEVEL_METRIC); + Optional measure = toMeasure(EMPTY_BATCH_MEASURE, SOME_LEVEL_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -77,7 +76,7 @@ public class BatchMeasureToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_invalid_string_value_for_LEVEL_Metric() { - Optional measure = underTest.toMeasure(ScannerReport.Measure.newBuilder().setStringValue(StringValue.newBuilder().setValue("trololo")).build(), SOME_LEVEL_METRIC); + Optional measure = toMeasure(ScannerReport.Measure.newBuilder().setStringValue(StringValue.newBuilder().setValue("trololo")).build(), SOME_LEVEL_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -85,7 +84,7 @@ public class BatchMeasureToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_value_in_wrong_case_for_LEVEL_Metric() { - Optional measure = underTest.toMeasure(ScannerReport.Measure.newBuilder().setStringValue(StringValue.newBuilder().setValue("waRn")).build(), SOME_LEVEL_METRIC); + Optional measure = toMeasure(ScannerReport.Measure.newBuilder().setStringValue(StringValue.newBuilder().setValue("waRn")).build(), SOME_LEVEL_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -99,7 +98,7 @@ public class BatchMeasureToMeasureTest { } private void verify_toMeasure_returns_value_for_LEVEL_Metric(Measure.Level expectedQualityGateStatus) { - Optional measure = underTest.toMeasure(ScannerReport.Measure.newBuilder().setStringValue(StringValue.newBuilder().setValue(expectedQualityGateStatus.name())).build(), + Optional measure = toMeasure(ScannerReport.Measure.newBuilder().setStringValue(StringValue.newBuilder().setValue(expectedQualityGateStatus.name())).build(), SOME_LEVEL_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LEVEL); @@ -112,7 +111,7 @@ public class BatchMeasureToMeasureTest { .setStringValue(StringValue.newBuilder().setValue(Measure.Level.OK.name())) .build(); - Optional measure = underTest.toMeasure(batchMeasure, SOME_LEVEL_METRIC); + Optional measure = toMeasure(batchMeasure, SOME_LEVEL_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LEVEL); @@ -131,7 +130,7 @@ public class BatchMeasureToMeasureTest { .setStringValue(StringValue.newBuilder().setValue(expectedLevel.name())) .build(); - Optional measure = underTest.toMeasure(batchMeasure, SOME_LEVEL_METRIC); + Optional measure = toMeasure(batchMeasure, SOME_LEVEL_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getLevelValue()).isEqualTo(expectedLevel); @@ -139,7 +138,7 @@ public class BatchMeasureToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_no_value_for_Int_Metric() { - Optional measure = underTest.toMeasure(EMPTY_BATCH_MEASURE, SOME_INT_METRIC); + Optional measure = toMeasure(EMPTY_BATCH_MEASURE, SOME_INT_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -151,7 +150,7 @@ public class BatchMeasureToMeasureTest { .setIntValue(IntValue.newBuilder().setValue(10).setData(SOME_DATA)) .build(); - Optional measure = underTest.toMeasure(batchMeasure, SOME_INT_METRIC); + Optional measure = toMeasure(batchMeasure, SOME_INT_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.INT); @@ -161,7 +160,7 @@ public class BatchMeasureToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_no_value_for_Long_Metric() { - Optional measure = underTest.toMeasure(EMPTY_BATCH_MEASURE, SOME_LONG_METRIC); + Optional measure = toMeasure(EMPTY_BATCH_MEASURE, SOME_LONG_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -169,7 +168,7 @@ public class BatchMeasureToMeasureTest { @Test public void toMeasure_returns_long_part_of_value_in_dto_for_Long_Metric() { - Optional measure = underTest.toMeasure(ScannerReport.Measure.newBuilder().setLongValue(LongValue.newBuilder().setValue(15L)).build(), SOME_LONG_METRIC); + Optional measure = toMeasure(ScannerReport.Measure.newBuilder().setLongValue(LongValue.newBuilder().setValue(15L)).build(), SOME_LONG_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LONG); @@ -182,7 +181,7 @@ public class BatchMeasureToMeasureTest { .setLongValue(LongValue.newBuilder().setValue(10L).setData(SOME_DATA)) .build(); - Optional measure = underTest.toMeasure(batchMeasure, SOME_LONG_METRIC); + Optional measure = toMeasure(batchMeasure, SOME_LONG_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LONG); @@ -192,7 +191,7 @@ public class BatchMeasureToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_no_value_for_Double_Metric() { - Optional measure = underTest.toMeasure(EMPTY_BATCH_MEASURE, SOME_DOUBLE_METRIC); + Optional measure = toMeasure(EMPTY_BATCH_MEASURE, SOME_DOUBLE_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -204,7 +203,7 @@ public class BatchMeasureToMeasureTest { .setDoubleValue(DoubleValue.newBuilder().setValue(10.6395d).setData(SOME_DATA)) .build(); - Optional measure = underTest.toMeasure(batchMeasure, SOME_DOUBLE_METRIC); + Optional measure = toMeasure(batchMeasure, SOME_DOUBLE_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.DOUBLE); @@ -214,7 +213,7 @@ public class BatchMeasureToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_no_value_for_Boolean_metric() { - Optional measure = underTest.toMeasure(EMPTY_BATCH_MEASURE, SOME_BOOLEAN_METRIC); + Optional measure = toMeasure(EMPTY_BATCH_MEASURE, SOME_BOOLEAN_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -227,7 +226,7 @@ public class BatchMeasureToMeasureTest { } private void verify_toMeasure_returns_false_value_if_dto_has_invalid_value_for_Boolean_metric(boolean expected) { - Optional measure = underTest.toMeasure(ScannerReport.Measure.newBuilder().setBooleanValue(BoolValue.newBuilder().setValue(expected)).build(), SOME_BOOLEAN_METRIC); + Optional measure = toMeasure(ScannerReport.Measure.newBuilder().setBooleanValue(BoolValue.newBuilder().setValue(expected)).build(), SOME_BOOLEAN_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.BOOLEAN); @@ -239,7 +238,7 @@ public class BatchMeasureToMeasureTest { ScannerReport.Measure batchMeasure = ScannerReport.Measure.newBuilder() .setBooleanValue(BoolValue.newBuilder().setValue(true).setData(SOME_DATA)).build(); - Optional measure = underTest.toMeasure(batchMeasure, SOME_BOOLEAN_METRIC); + Optional measure = toMeasure(batchMeasure, SOME_BOOLEAN_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.BOOLEAN); @@ -249,7 +248,7 @@ public class BatchMeasureToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_no_value_for_String_Metric() { - Optional measure = underTest.toMeasure(EMPTY_BATCH_MEASURE, SOME_STRING_METRIC); + Optional measure = toMeasure(EMPTY_BATCH_MEASURE, SOME_STRING_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -261,7 +260,7 @@ public class BatchMeasureToMeasureTest { .setStringValue(StringValue.newBuilder().setValue(SOME_DATA)) .build(); - Optional measure = underTest.toMeasure(batchMeasure, SOME_STRING_METRIC); + Optional measure = toMeasure(batchMeasure, SOME_STRING_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.STRING); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/LiveMeasureDtoToMeasureTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/LiveMeasureDtoToMeasureTest.java index bd0739dc0db..587fbacf77a 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/LiveMeasureDtoToMeasureTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/LiveMeasureDtoToMeasureTest.java @@ -31,6 +31,7 @@ import org.sonar.db.measure.LiveMeasureDto; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.sonar.ce.task.projectanalysis.measure.LiveMeasureDtoToMeasure.*; @RunWith(DataProviderRunner.class) public class LiveMeasureDtoToMeasureTest { @@ -42,63 +43,61 @@ public class LiveMeasureDtoToMeasureTest { private static final Metric SOME_LEVEL_METRIC = new MetricImpl("42", "level", "name", Metric.MetricType.LEVEL); private static final LiveMeasureDto EMPTY_MEASURE_DTO = new LiveMeasureDto(); - private LiveMeasureDtoToMeasure underTest = new LiveMeasureDtoToMeasure(); - @Test public void toMeasure_returns_absent_for_null_argument() { - assertThat(underTest.toMeasure(null, SOME_INT_METRIC)).isNotPresent(); + assertThat(toMeasure(null, SOME_INT_METRIC)).isNotPresent(); } @Test public void toMeasure_throws_NPE_if_metric_argument_is_null() { - assertThatThrownBy(() -> underTest.toMeasure(EMPTY_MEASURE_DTO, null)) + assertThatThrownBy(() -> toMeasure(EMPTY_MEASURE_DTO, null)) .isInstanceOf(NullPointerException.class); } @Test public void toMeasure_throws_NPE_if_both_arguments_are_null() { - assertThatThrownBy(() -> underTest.toMeasure(null, null)) + assertThatThrownBy(() -> toMeasure(null, null)) .isInstanceOf(NullPointerException.class); } @Test public void toMeasure_returns_no_value_if_dto_has_no_data_for_Level_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_LEVEL_METRIC); + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_LEVEL_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); } @Test public void toMeasure_returns_no_value_if_dto_has_invalid_data_for_Level_Metric() { - Optional measure = underTest.toMeasure(new LiveMeasureDto().setData("trololo"), SOME_LEVEL_METRIC); + Optional measure = toMeasure(new LiveMeasureDto().setData("trololo"), SOME_LEVEL_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); } @Test public void toMeasure_returns_no_value_if_dta_has_data_in_wrong_case_for_Level_Metric() { - Optional measure = underTest.toMeasure(new LiveMeasureDto().setData("waRn"), SOME_LEVEL_METRIC); + Optional measure = toMeasure(new LiveMeasureDto().setData("waRn"), SOME_LEVEL_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); } @Test public void toMeasure_returns_no_QualityGateStatus_if_dto_has_no_alertStatus_for_Level_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_STRING_METRIC); + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_STRING_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().hasQualityGateStatus()).isFalse(); } @Test public void toMeasure_returns_no_QualityGateStatus_if_alertStatus_has_invalid_data_for_Level_Metric() { - Optional measure = underTest.toMeasure(new LiveMeasureDto().setData("trololo"), SOME_STRING_METRIC); + Optional measure = toMeasure(new LiveMeasureDto().setData("trololo"), SOME_STRING_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().hasQualityGateStatus()).isFalse(); } @Test public void toMeasure_returns_no_QualityGateStatus_if_alertStatus_has_data_in_wrong_case_for_Level_Metric() { - Optional measure = underTest.toMeasure(new LiveMeasureDto().setData("waRn"), SOME_STRING_METRIC); + Optional measure = toMeasure(new LiveMeasureDto().setData("waRn"), SOME_STRING_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().hasQualityGateStatus()).isFalse(); } @@ -111,7 +110,7 @@ public class LiveMeasureDtoToMeasureTest { } private void verify_toMeasure_returns_value_for_LEVEL_Metric(Level expectedLevel) { - Optional measure = underTest.toMeasure(new LiveMeasureDto().setData(expectedLevel.name()), SOME_LEVEL_METRIC); + Optional measure = toMeasure(new LiveMeasureDto().setData(expectedLevel.name()), SOME_LEVEL_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LEVEL); assertThat(measure.get().getLevelValue()).isEqualTo(expectedLevel); @@ -119,7 +118,7 @@ public class LiveMeasureDtoToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_no_value_for_Int_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_INT_METRIC); + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_INT_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -127,7 +126,7 @@ public class LiveMeasureDtoToMeasureTest { @Test public void toMeasure_returns_int_part_of_value_in_dto_for_Int_Metric() { - Optional measure = underTest.toMeasure(new LiveMeasureDto().setValue(1.5d), SOME_INT_METRIC); + Optional measure = toMeasure(new LiveMeasureDto().setValue(1.5d), SOME_INT_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.INT); @@ -136,7 +135,7 @@ public class LiveMeasureDtoToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_no_value_for_Long_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_LONG_METRIC); + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_LONG_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -144,7 +143,7 @@ public class LiveMeasureDtoToMeasureTest { @Test public void toMeasure_returns_long_part_of_value_in_dto_for_Long_Metric() { - Optional measure = underTest.toMeasure(new LiveMeasureDto().setValue(1.5d), SOME_LONG_METRIC); + Optional measure = toMeasure(new LiveMeasureDto().setValue(1.5d), SOME_LONG_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LONG); @@ -153,7 +152,7 @@ public class LiveMeasureDtoToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_no_value_for_Double_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_DOUBLE_METRIC); + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_DOUBLE_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -161,7 +160,7 @@ public class LiveMeasureDtoToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_no_value_for_Boolean_metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_BOOLEAN_METRIC); + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_BOOLEAN_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -169,7 +168,7 @@ public class LiveMeasureDtoToMeasureTest { @Test public void toMeasure_returns_false_value_if_dto_has_invalid_value_for_Boolean_metric() { - Optional measure = underTest.toMeasure(new LiveMeasureDto().setValue(1.987d), SOME_BOOLEAN_METRIC); + Optional measure = toMeasure(new LiveMeasureDto().setValue(1.987d), SOME_BOOLEAN_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.BOOLEAN); @@ -178,7 +177,7 @@ public class LiveMeasureDtoToMeasureTest { @Test public void toMeasure_returns_no_value_if_dto_has_no_value_for_String_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_STRING_METRIC); + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_STRING_METRIC); assertThat(measure).isPresent(); assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); @@ -190,7 +189,7 @@ public class LiveMeasureDtoToMeasureTest { LiveMeasureDto LiveMeasureDto = new LiveMeasureDto() .setValue(0.12345); - Optional measure = underTest.toMeasure(LiveMeasureDto, metric); + Optional measure = toMeasure(LiveMeasureDto, metric); assertThat(measure.get().getDoubleValue()).isEqualTo(0.12345, Offset.offset(0.000001)); } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/MeasureDtoToMeasureTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/MeasureDtoToMeasureTest.java deleted file mode 100644 index 0856ebe3298..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/MeasureDtoToMeasureTest.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.ce.task.projectanalysis.measure; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import java.util.Optional; -import org.assertj.core.data.Offset; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.sonar.ce.task.projectanalysis.measure.Measure.Level; -import org.sonar.ce.task.projectanalysis.metric.Metric; -import org.sonar.ce.task.projectanalysis.metric.MetricImpl; -import org.sonar.db.measure.MeasureDto; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -@RunWith(DataProviderRunner.class) -public class MeasureDtoToMeasureTest { - private static final Metric SOME_INT_METRIC = new MetricImpl("42", "int", "name", Metric.MetricType.INT); - private static final Metric SOME_LONG_METRIC = new MetricImpl("42", "long", "name", Metric.MetricType.WORK_DUR); - private static final Metric SOME_DOUBLE_METRIC = new MetricImpl("42", "double", "name", Metric.MetricType.FLOAT); - private static final Metric SOME_STRING_METRIC = new MetricImpl("42", "string", "name", Metric.MetricType.STRING); - private static final Metric SOME_BOOLEAN_METRIC = new MetricImpl("42", "boolean", "name", Metric.MetricType.BOOL); - private static final Metric SOME_LEVEL_METRIC = new MetricImpl("42", "level", "name", Metric.MetricType.LEVEL); - - private static final String SOME_DATA = "some_data man!"; - private static final String SOME_ALERT_TEXT = "some alert text_be_careFul!"; - private static final MeasureDto EMPTY_MEASURE_DTO = new MeasureDto(); - - - private MeasureDtoToMeasure underTest = new MeasureDtoToMeasure(); - - @Test - public void toMeasure_returns_absent_for_null_argument() { - assertThat(underTest.toMeasure(null, SOME_INT_METRIC)).isNotPresent(); - } - - @Test - public void toMeasure_throws_NPE_if_metric_argument_is_null() { - assertThatThrownBy(() -> underTest.toMeasure(EMPTY_MEASURE_DTO, null)) - .isInstanceOf(NullPointerException.class); - } - - @Test - public void toMeasure_throws_NPE_if_both_arguments_are_null() { - assertThatThrownBy(() -> underTest.toMeasure(null, null)) - .isInstanceOf(NullPointerException.class); - } - - @Test - public void toMeasure_returns_no_value_if_dto_has_no_data_for_Level_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_LEVEL_METRIC); - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); - } - - @Test - public void toMeasure_returns_no_value_if_dto_has_invalid_data_for_Level_Metric() { - Optional measure = underTest.toMeasure(new MeasureDto().setData("trololo"), SOME_LEVEL_METRIC); - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); - } - - @Test - public void toMeasure_returns_no_value_if_dta_has_data_in_wrong_case_for_Level_Metric() { - Optional measure = underTest.toMeasure(new MeasureDto().setData("waRn"), SOME_LEVEL_METRIC); - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); - } - - @Test - public void toMeasure_returns_no_QualityGateStatus_if_dto_has_no_alertStatus_for_Level_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_STRING_METRIC); - assertThat(measure).isPresent(); - assertThat(measure.get().hasQualityGateStatus()).isFalse(); - } - - @Test - public void toMeasure_returns_no_QualityGateStatus_if_alertStatus_has_invalid_data_for_Level_Metric() { - Optional measure = underTest.toMeasure(new MeasureDto().setData("trololo"), SOME_STRING_METRIC); - assertThat(measure).isPresent(); - assertThat(measure.get().hasQualityGateStatus()).isFalse(); - } - - @Test - public void toMeasure_returns_no_QualityGateStatus_if_alertStatus_has_data_in_wrong_case_for_Level_Metric() { - Optional measure = underTest.toMeasure(new MeasureDto().setData("waRn"), SOME_STRING_METRIC); - assertThat(measure).isPresent(); - assertThat(measure.get().hasQualityGateStatus()).isFalse(); - } - - @Test - public void toMeasure_returns_value_for_LEVEL_Metric() { - for (Level level : Level.values()) { - verify_toMeasure_returns_value_for_LEVEL_Metric(level); - } - } - - private void verify_toMeasure_returns_value_for_LEVEL_Metric(Level expectedLevel) { - Optional measure = underTest.toMeasure(new MeasureDto().setData(expectedLevel.name()), SOME_LEVEL_METRIC); - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LEVEL); - assertThat(measure.get().getLevelValue()).isEqualTo(expectedLevel); - } - - @Test - public void toMeasure_for_LEVEL_Metric_can_have_an_qualityGateStatus() { - MeasureDto measureDto = new MeasureDto().setData(Level.OK.name()).setAlertStatus(Level.ERROR.name()).setAlertText(SOME_ALERT_TEXT); - - Optional measure = underTest.toMeasure(measureDto, SOME_LEVEL_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LEVEL); - assertThat(measure.get().getLevelValue()).isEqualTo(Level.OK); - assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.ERROR); - assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); - } - - @Test - public void toMeasure_for_LEVEL_Metric_ignores_data() { - MeasureDto measureDto = new MeasureDto().setAlertStatus(Level.ERROR.name()).setData(SOME_DATA); - - Optional measure = underTest.toMeasure(measureDto, SOME_LEVEL_METRIC); - - assertThat(measure).isPresent(); - - assertThatThrownBy(() ->measure.get().getStringValue()) - .isInstanceOf(IllegalStateException.class); - } - - @Test - public void toMeasure_returns_no_value_if_dto_has_no_value_for_Int_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_INT_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); - } - - @Test - public void toMeasure_returns_int_part_of_value_in_dto_for_Int_Metric() { - Optional measure = underTest.toMeasure(new MeasureDto().setValue(1.5d), SOME_INT_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.INT); - assertThat(measure.get().getIntValue()).isOne(); - } - - @Test - public void toMeasure_maps_data_and_alert_properties_in_dto_for_Int_Metric() { - MeasureDto measureDto = new MeasureDto().setValue(10d).setData(SOME_DATA).setAlertStatus(Level.OK.name()).setAlertText(SOME_ALERT_TEXT); - - Optional measure = underTest.toMeasure(measureDto, SOME_INT_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.INT); - assertThat(measure.get().getIntValue()).isEqualTo(10); - assertThat(measure.get().getData()).isEqualTo(SOME_DATA); - assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK); - assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); - } - - @Test - public void toMeasure_returns_no_value_if_dto_has_no_value_for_Long_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_LONG_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); - } - - @Test - public void toMeasure_returns_long_part_of_value_in_dto_for_Long_Metric() { - Optional measure = underTest.toMeasure(new MeasureDto().setValue(1.5d), SOME_LONG_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LONG); - assertThat(measure.get().getLongValue()).isOne(); - } - - @Test - public void toMeasure_maps_data_and_alert_properties_in_dto_for_Long_Metric() { - MeasureDto measureDto = new MeasureDto().setValue(10d).setData(SOME_DATA).setAlertStatus(Level.OK.name()).setAlertText(SOME_ALERT_TEXT); - - Optional measure = underTest.toMeasure(measureDto, SOME_LONG_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LONG); - assertThat(measure.get().getLongValue()).isEqualTo(10); - assertThat(measure.get().getData()).isEqualTo(SOME_DATA); - assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK); - assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); - } - - @Test - public void toMeasure_returns_no_value_if_dto_has_no_value_for_Double_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_DOUBLE_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); - } - - @Test - public void toMeasure_maps_data_and_alert_properties_in_dto_for_Double_Metric() { - MeasureDto measureDto = new MeasureDto().setValue(10.6395d).setData(SOME_DATA).setAlertStatus(Level.OK.name()).setAlertText(SOME_ALERT_TEXT); - - Optional measure = underTest.toMeasure(measureDto, SOME_DOUBLE_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.DOUBLE); - assertThat(measure.get().getDoubleValue()).isEqualTo(10.6395d); - assertThat(measure.get().getData()).isEqualTo(SOME_DATA); - assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK); - assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); - } - - @Test - public void toMeasure_returns_no_value_if_dto_has_no_value_for_Boolean_metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_BOOLEAN_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); - } - - @Test - public void toMeasure_returns_false_value_if_dto_has_invalid_value_for_Boolean_metric() { - Optional measure = underTest.toMeasure(new MeasureDto().setValue(1.987d), SOME_BOOLEAN_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.BOOLEAN); - assertThat(measure.get().getBooleanValue()).isFalse(); - } - - @Test - public void toMeasure_maps_data_and_alert_properties_in_dto_for_Boolean_metric() { - MeasureDto measureDto = new MeasureDto().setValue(1d).setData(SOME_DATA).setAlertStatus(Level.OK.name()).setAlertText(SOME_ALERT_TEXT); - - Optional measure = underTest.toMeasure(measureDto, SOME_BOOLEAN_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.BOOLEAN); - assertThat(measure.get().getBooleanValue()).isTrue(); - assertThat(measure.get().getData()).isEqualTo(SOME_DATA); - assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK); - assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); - } - - @Test - public void toMeasure_returns_no_value_if_dto_has_no_value_for_String_Metric() { - Optional measure = underTest.toMeasure(EMPTY_MEASURE_DTO, SOME_STRING_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); - } - - @Test - public void toMeasure_maps_alert_properties_in_dto_for_String_Metric() { - MeasureDto measureDto = new MeasureDto().setData(SOME_DATA).setAlertStatus(Level.OK.name()).setAlertText(SOME_ALERT_TEXT); - - Optional measure = underTest.toMeasure(measureDto, SOME_STRING_METRIC); - - assertThat(measure).isPresent(); - assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.STRING); - assertThat(measure.get().getStringValue()).isEqualTo(SOME_DATA); - assertThat(measure.get().getData()).isEqualTo(SOME_DATA); - assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK); - assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); - } - - @DataProvider - public static Object[][] all_types_MeasureDtos() { - return new Object[][] { - {new MeasureDto().setValue(1d), SOME_BOOLEAN_METRIC}, - {new MeasureDto().setValue(1d), SOME_INT_METRIC}, - {new MeasureDto().setValue(1d), SOME_LONG_METRIC}, - {new MeasureDto().setValue(1d), SOME_DOUBLE_METRIC}, - {new MeasureDto().setData("1"), SOME_STRING_METRIC}, - {new MeasureDto().setData(Measure.Level.OK.name()), SOME_LEVEL_METRIC} - }; - } - - @Test - public void toMeasure_should_not_loose_decimals_of_float_values() { - MetricImpl metric = new MetricImpl("42", "double", "name", Metric.MetricType.FLOAT, 5, null, false, false); - MeasureDto measureDto = new MeasureDto() - .setValue(0.12345); - - Optional measure = underTest.toMeasure(measureDto, metric); - - assertThat(measure.get().getDoubleValue()).isEqualTo(0.12345, Offset.offset(0.000001)); - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/MeasureToMeasureDtoTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/MeasureToMeasureDtoTest.java index e06243d073f..763e5ddb544 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/MeasureToMeasureDtoTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/MeasureToMeasureDtoTest.java @@ -33,7 +33,7 @@ import org.sonar.ce.task.projectanalysis.component.ReportComponent; import org.sonar.ce.task.projectanalysis.metric.Metric; import org.sonar.ce.task.projectanalysis.metric.MetricImpl; import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -66,14 +66,15 @@ public class MeasureToMeasureDtoTest { } @Test - public void toMeasureDto_throws_NPE_if_Measure_arg_is_null() { - assertThatThrownBy(() -> underTest.toMeasureDto(null, SOME_METRIC, SOME_COMPONENT)) + public void toProjectMeasureDto_throws_NPE_if_Measure_arg_is_null() { + assertThatThrownBy(() -> underTest.toProjectMeasureDto(null, SOME_METRIC, SOME_COMPONENT)) .isInstanceOf(NullPointerException.class); } @Test - public void toMeasureDto_throws_NPE_if_Metric_arg_is_null() { - assertThatThrownBy(() -> underTest.toMeasureDto(Measure.newMeasureBuilder().createNoValue(), null, SOME_COMPONENT)) + public void toProjectMeasureDto_throws_NPE_if_Metric_arg_is_null() { + Measure measure = Measure.newMeasureBuilder().createNoValue(); + assertThatThrownBy(() -> underTest.toProjectMeasureDto(measure, null, SOME_COMPONENT)) .isInstanceOf(NullPointerException.class); } @@ -91,79 +92,79 @@ public class MeasureToMeasureDtoTest { @Test @UseDataProvider("all_types_Measures") - public void toMeasureDto_returns_Dto_without_alertStatus_nor_alertText_if_Measure_has_no_QualityGateStatus(Measure measure, Metric metric) { - MeasureDto measureDto = underTest.toMeasureDto(measure, metric, SOME_COMPONENT); + public void toProjectMeasureDto_returns_Dto_without_alertStatus_nor_alertText_if_Measure_has_no_QualityGateStatus(Measure measure, Metric metric) { + ProjectMeasureDto projectMeasureDto = underTest.toProjectMeasureDto(measure, metric, SOME_COMPONENT); - assertThat(measureDto.getAlertStatus()).isNull(); - assertThat(measureDto.getAlertText()).isNull(); + assertThat(projectMeasureDto.getAlertStatus()).isNull(); + assertThat(projectMeasureDto.getAlertText()).isNull(); } @Test - public void toMeasureDto_returns_Dto_with_alertStatus_and_alertText_if_Measure_has_QualityGateStatus() { + public void toProjectMeasureDto_returns_Dto_with_alertStatus_and_alertText_if_Measure_has_QualityGateStatus() { String alertText = "some error"; - MeasureDto measureDto = underTest.toMeasureDto(Measure.newMeasureBuilder().setQualityGateStatus(new QualityGateStatus(Measure.Level.ERROR, alertText)).create(SOME_STRING), + ProjectMeasureDto projectMeasureDto = underTest.toProjectMeasureDto(Measure.newMeasureBuilder().setQualityGateStatus(new QualityGateStatus(Measure.Level.ERROR, alertText)).create(SOME_STRING), SOME_STRING_METRIC, SOME_COMPONENT); - assertThat(measureDto.getAlertStatus()).isEqualTo(Measure.Level.ERROR.name()); - assertThat(measureDto.getAlertText()).isEqualTo(alertText); + assertThat(projectMeasureDto.getAlertStatus()).isEqualTo(Measure.Level.ERROR.name()); + assertThat(projectMeasureDto.getAlertText()).isEqualTo(alertText); } @Test @UseDataProvider("all_types_Measures") - public void toMeasureDto_set_componentId_and_snapshotId_from_method_arguments(Measure measure, Metric metric) { - MeasureDto measureDto = underTest.toMeasureDto(measure, metric, SOME_COMPONENT); + public void toProjectMeasureDto_set_componentId_and_snapshotId_from_method_arguments(Measure measure, Metric metric) { + ProjectMeasureDto projectMeasureDto = underTest.toProjectMeasureDto(measure, metric, SOME_COMPONENT); - assertThat(measureDto.getComponentUuid()).isEqualTo(SOME_COMPONENT.getUuid()); + assertThat(projectMeasureDto.getComponentUuid()).isEqualTo(SOME_COMPONENT.getUuid()); } @Test - public void toMeasureDto_maps_value_to_1_or_0_and_data_from_data_field_for_BOOLEAN_metric() { - MeasureDto trueMeasureDto = underTest.toMeasureDto(Measure.newMeasureBuilder().create(true, SOME_DATA), SOME_BOOLEAN_METRIC, SOME_COMPONENT); + public void toProjectMeasureDto_maps_value_to_Project_1_or_0_and_data_from_data_field_for_BOOLEAN_metric() { + ProjectMeasureDto trueMeasureDto = underTest.toProjectMeasureDto(Measure.newMeasureBuilder().create(true, SOME_DATA), SOME_BOOLEAN_METRIC, SOME_COMPONENT); assertThat(trueMeasureDto.getValue()).isEqualTo(1d); assertThat(trueMeasureDto.getData()).isEqualTo(SOME_DATA); - MeasureDto falseMeasureDto = underTest.toMeasureDto(Measure.newMeasureBuilder().create(false, SOME_DATA), SOME_BOOLEAN_METRIC, SOME_COMPONENT); + ProjectMeasureDto falseMeasureDto = underTest.toProjectMeasureDto(Measure.newMeasureBuilder().create(false, SOME_DATA), SOME_BOOLEAN_METRIC, SOME_COMPONENT); assertThat(falseMeasureDto.getValue()).isEqualTo(0d); assertThat(falseMeasureDto.getData()).isEqualTo(SOME_DATA); } @Test - public void toMeasureDto_maps_value_and_data_from_data_field_for_INT_metric() { - MeasureDto trueMeasureDto = underTest.toMeasureDto(Measure.newMeasureBuilder().create(123, SOME_DATA), SOME_INT_METRIC, SOME_COMPONENT); + public void toProjectMeasureDto_maps_value_and_data_from_data_field_for_INT_metric() { + ProjectMeasureDto trueMeasureDto = underTest.toProjectMeasureDto(Measure.newMeasureBuilder().create(123, SOME_DATA), SOME_INT_METRIC, SOME_COMPONENT); assertThat(trueMeasureDto.getValue()).isEqualTo(123); assertThat(trueMeasureDto.getData()).isEqualTo(SOME_DATA); } @Test - public void toMeasureDto_maps_value_and_data_from_data_field_for_LONG_metric() { - MeasureDto trueMeasureDto = underTest.toMeasureDto(Measure.newMeasureBuilder().create((long) 456, SOME_DATA), SOME_LONG_METRIC, SOME_COMPONENT); + public void toProjectMeasureDto_maps_value_and_data_from_data_field_for_LONG_metric() { + ProjectMeasureDto trueMeasureDto = underTest.toProjectMeasureDto(Measure.newMeasureBuilder().create((long) 456, SOME_DATA), SOME_LONG_METRIC, SOME_COMPONENT); assertThat(trueMeasureDto.getValue()).isEqualTo(456); assertThat(trueMeasureDto.getData()).isEqualTo(SOME_DATA); } @Test - public void toMeasureDto_maps_value_and_data_from_data_field_for_DOUBLE_metric() { - MeasureDto trueMeasureDto = underTest.toMeasureDto(Measure.newMeasureBuilder().create(789, 1, SOME_DATA), SOME_DOUBLE_METRIC, SOME_COMPONENT); + public void toProjectMeasureDto_maps_value_and_data_from_data_field_for_DOUBLE_metric() { + ProjectMeasureDto trueMeasureDto = underTest.toProjectMeasureDto(Measure.newMeasureBuilder().create(789, 1, SOME_DATA), SOME_DOUBLE_METRIC, SOME_COMPONENT); assertThat(trueMeasureDto.getValue()).isEqualTo(789); assertThat(trueMeasureDto.getData()).isEqualTo(SOME_DATA); } @Test - public void toMeasureDto_maps_to_only_data_for_STRING_metric() { - MeasureDto trueMeasureDto = underTest.toMeasureDto(Measure.newMeasureBuilder().create(SOME_STRING), SOME_STRING_METRIC, SOME_COMPONENT); + public void toProjectMeasureDto_maps_to_Project_only_data_for_STRING_metric() { + ProjectMeasureDto trueMeasureDto = underTest.toProjectMeasureDto(Measure.newMeasureBuilder().create(SOME_STRING), SOME_STRING_METRIC, SOME_COMPONENT); assertThat(trueMeasureDto.getValue()).isNull(); assertThat(trueMeasureDto.getData()).isEqualTo(SOME_STRING); } @Test - public void toMeasureDto_maps_name_of_Level_to_data_and_has_no_value_for_LEVEL_metric() { - MeasureDto trueMeasureDto = underTest.toMeasureDto(Measure.newMeasureBuilder().create(Measure.Level.OK), SOME_LEVEL_METRIC, SOME_COMPONENT); + public void toProjectMeasureDto_maps_name_of_Level_to_Project_data_and_has_no_value_for_LEVEL_metric() { + ProjectMeasureDto trueMeasureDto = underTest.toProjectMeasureDto(Measure.newMeasureBuilder().create(Measure.Level.OK), SOME_LEVEL_METRIC, SOME_COMPONENT); assertThat(trueMeasureDto.getValue()).isNull(); assertThat(trueMeasureDto.getData()).isEqualTo(Measure.Level.OK.name()); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/ProjectMeasureDtoToMeasureTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/ProjectMeasureDtoToMeasureTest.java new file mode 100644 index 00000000000..44895011e0d --- /dev/null +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/ProjectMeasureDtoToMeasureTest.java @@ -0,0 +1,307 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.ce.task.projectanalysis.measure; + +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import java.util.Optional; +import org.assertj.core.data.Offset; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.sonar.ce.task.projectanalysis.measure.Measure.Level; +import org.sonar.ce.task.projectanalysis.metric.Metric; +import org.sonar.ce.task.projectanalysis.metric.MetricImpl; +import org.sonar.db.measure.ProjectMeasureDto; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.sonar.ce.task.projectanalysis.measure.ProjectMeasureDtoToMeasure.*; + +@RunWith(DataProviderRunner.class) +public class ProjectMeasureDtoToMeasureTest { + private static final Metric SOME_INT_METRIC = new MetricImpl("42", "int", "name", Metric.MetricType.INT); + private static final Metric SOME_LONG_METRIC = new MetricImpl("42", "long", "name", Metric.MetricType.WORK_DUR); + private static final Metric SOME_DOUBLE_METRIC = new MetricImpl("42", "double", "name", Metric.MetricType.FLOAT); + private static final Metric SOME_STRING_METRIC = new MetricImpl("42", "string", "name", Metric.MetricType.STRING); + private static final Metric SOME_BOOLEAN_METRIC = new MetricImpl("42", "boolean", "name", Metric.MetricType.BOOL); + private static final Metric SOME_LEVEL_METRIC = new MetricImpl("42", "level", "name", Metric.MetricType.LEVEL); + + private static final String SOME_DATA = "some_data man!"; + private static final String SOME_ALERT_TEXT = "some alert text_be_careFul!"; + private static final ProjectMeasureDto EMPTY_MEASURE_DTO = new ProjectMeasureDto(); + + @Test + public void toMeasure_returns_absent_for_null_argument() { + assertThat(toMeasure(null, SOME_INT_METRIC)).isNotPresent(); + } + + @Test + public void toMeasure_throws_NPE_if_metric_argument_is_null() { + assertThatThrownBy(() -> toMeasure(EMPTY_MEASURE_DTO, null)) + .isInstanceOf(NullPointerException.class); + } + + @Test + public void toMeasure_throws_NPE_if_both_arguments_are_null() { + assertThatThrownBy(() -> toMeasure(null, null)) + .isInstanceOf(NullPointerException.class); + } + + @Test + public void toMeasure_returns_no_value_if_dto_has_no_data_for_Level_Metric() { + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_LEVEL_METRIC); + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); + } + + @Test + public void toMeasure_returns_no_value_if_dto_has_invalid_data_for_Level_Metric() { + Optional measure = toMeasure(new ProjectMeasureDto().setData("trololo"), SOME_LEVEL_METRIC); + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); + } + + @Test + public void toMeasure_returns_no_value_if_dta_has_data_in_wrong_case_for_Level_Metric() { + Optional measure = toMeasure(new ProjectMeasureDto().setData("waRn"), SOME_LEVEL_METRIC); + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); + } + + @Test + public void toMeasure_returns_no_QualityGateStatus_if_dto_has_no_alertStatus_for_Level_Metric() { + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_STRING_METRIC); + assertThat(measure).isPresent(); + assertThat(measure.get().hasQualityGateStatus()).isFalse(); + } + + @Test + public void toMeasure_returns_no_QualityGateStatus_if_alertStatus_has_invalid_data_for_Level_Metric() { + Optional measure = toMeasure(new ProjectMeasureDto().setData("trololo"), SOME_STRING_METRIC); + assertThat(measure).isPresent(); + assertThat(measure.get().hasQualityGateStatus()).isFalse(); + } + + @Test + public void toMeasure_returns_no_QualityGateStatus_if_alertStatus_has_data_in_wrong_case_for_Level_Metric() { + Optional measure = toMeasure(new ProjectMeasureDto().setData("waRn"), SOME_STRING_METRIC); + assertThat(measure).isPresent(); + assertThat(measure.get().hasQualityGateStatus()).isFalse(); + } + + @Test + public void toMeasure_returns_value_for_LEVEL_Metric() { + for (Level level : Level.values()) { + verify_toMeasure_returns_value_for_LEVEL_Metric(level); + } + } + + private void verify_toMeasure_returns_value_for_LEVEL_Metric(Level expectedLevel) { + Optional measure = toMeasure(new ProjectMeasureDto().setData(expectedLevel.name()), SOME_LEVEL_METRIC); + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LEVEL); + assertThat(measure.get().getLevelValue()).isEqualTo(expectedLevel); + } + + @Test + public void toMeasure_for_LEVEL_Metric_can_have_an_qualityGateStatus() { + ProjectMeasureDto projectMeasureDto = new ProjectMeasureDto().setData(Level.OK.name()).setAlertStatus(Level.ERROR.name()).setAlertText(SOME_ALERT_TEXT); + + Optional measure = toMeasure(projectMeasureDto, SOME_LEVEL_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LEVEL); + assertThat(measure.get().getLevelValue()).isEqualTo(Level.OK); + assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.ERROR); + assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); + } + + @Test + public void toMeasure_for_LEVEL_Metric_ignores_data() { + ProjectMeasureDto projectMeasureDto = new ProjectMeasureDto().setAlertStatus(Level.ERROR.name()).setData(SOME_DATA); + + Optional measure = toMeasure(projectMeasureDto, SOME_LEVEL_METRIC); + + assertThat(measure).isPresent(); + + assertThatThrownBy(() ->measure.get().getStringValue()) + .isInstanceOf(IllegalStateException.class); + } + + @Test + public void toMeasure_returns_no_value_if_dto_has_no_value_for_Int_Metric() { + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_INT_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); + } + + @Test + public void toMeasure_returns_int_part_of_value_in_dto_for_Int_Metric() { + Optional measure = toMeasure(new ProjectMeasureDto().setValue(1.5d), SOME_INT_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.INT); + assertThat(measure.get().getIntValue()).isOne(); + } + + @Test + public void toMeasure_maps_data_and_alert_properties_in_dto_for_Int_Metric() { + ProjectMeasureDto projectMeasureDto = new ProjectMeasureDto().setValue(10d).setData(SOME_DATA).setAlertStatus(Level.OK.name()).setAlertText(SOME_ALERT_TEXT); + + Optional measure = toMeasure(projectMeasureDto, SOME_INT_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.INT); + assertThat(measure.get().getIntValue()).isEqualTo(10); + assertThat(measure.get().getData()).isEqualTo(SOME_DATA); + assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK); + assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); + } + + @Test + public void toMeasure_returns_no_value_if_dto_has_no_value_for_Long_Metric() { + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_LONG_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); + } + + @Test + public void toMeasure_returns_long_part_of_value_in_dto_for_Long_Metric() { + Optional measure = toMeasure(new ProjectMeasureDto().setValue(1.5d), SOME_LONG_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LONG); + assertThat(measure.get().getLongValue()).isOne(); + } + + @Test + public void toMeasure_maps_data_and_alert_properties_in_dto_for_Long_Metric() { + ProjectMeasureDto projectMeasureDto = new ProjectMeasureDto().setValue(10d).setData(SOME_DATA).setAlertStatus(Level.OK.name()).setAlertText(SOME_ALERT_TEXT); + + Optional measure = toMeasure(projectMeasureDto, SOME_LONG_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.LONG); + assertThat(measure.get().getLongValue()).isEqualTo(10); + assertThat(measure.get().getData()).isEqualTo(SOME_DATA); + assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK); + assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); + } + + @Test + public void toMeasure_returns_no_value_if_dto_has_no_value_for_Double_Metric() { + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_DOUBLE_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); + } + + @Test + public void toMeasure_maps_data_and_alert_properties_in_dto_for_Double_Metric() { + ProjectMeasureDto projectMeasureDto = new ProjectMeasureDto().setValue(10.6395d).setData(SOME_DATA).setAlertStatus(Level.OK.name()).setAlertText(SOME_ALERT_TEXT); + + Optional measure = toMeasure(projectMeasureDto, SOME_DOUBLE_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.DOUBLE); + assertThat(measure.get().getDoubleValue()).isEqualTo(10.6395d); + assertThat(measure.get().getData()).isEqualTo(SOME_DATA); + assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK); + assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); + } + + @Test + public void toMeasure_returns_no_value_if_dto_has_no_value_for_Boolean_metric() { + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_BOOLEAN_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); + } + + @Test + public void toMeasure_returns_false_value_if_dto_has_invalid_value_for_Boolean_metric() { + Optional measure = toMeasure(new ProjectMeasureDto().setValue(1.987d), SOME_BOOLEAN_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.BOOLEAN); + assertThat(measure.get().getBooleanValue()).isFalse(); + } + + @Test + public void toMeasure_maps_data_and_alert_properties_in_dto_for_Boolean_metric() { + ProjectMeasureDto projectMeasureDto = new ProjectMeasureDto().setValue(1d).setData(SOME_DATA).setAlertStatus(Level.OK.name()).setAlertText(SOME_ALERT_TEXT); + + Optional measure = toMeasure(projectMeasureDto, SOME_BOOLEAN_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.BOOLEAN); + assertThat(measure.get().getBooleanValue()).isTrue(); + assertThat(measure.get().getData()).isEqualTo(SOME_DATA); + assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK); + assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); + } + + @Test + public void toMeasure_returns_no_value_if_dto_has_no_value_for_String_Metric() { + Optional measure = toMeasure(EMPTY_MEASURE_DTO, SOME_STRING_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.NO_VALUE); + } + + @Test + public void toMeasure_maps_alert_properties_in_dto_for_String_Metric() { + ProjectMeasureDto projectMeasureDto = new ProjectMeasureDto().setData(SOME_DATA).setAlertStatus(Level.OK.name()).setAlertText(SOME_ALERT_TEXT); + + Optional measure = toMeasure(projectMeasureDto, SOME_STRING_METRIC); + + assertThat(measure).isPresent(); + assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.STRING); + assertThat(measure.get().getStringValue()).isEqualTo(SOME_DATA); + assertThat(measure.get().getData()).isEqualTo(SOME_DATA); + assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK); + assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT); + } + + @DataProvider + public static Object[][] all_types_MeasureDtos() { + return new Object[][] { + {new ProjectMeasureDto().setValue(1d), SOME_BOOLEAN_METRIC}, + {new ProjectMeasureDto().setValue(1d), SOME_INT_METRIC}, + {new ProjectMeasureDto().setValue(1d), SOME_LONG_METRIC}, + {new ProjectMeasureDto().setValue(1d), SOME_DOUBLE_METRIC}, + {new ProjectMeasureDto().setData("1"), SOME_STRING_METRIC}, + {new ProjectMeasureDto().setData(Measure.Level.OK.name()), SOME_LEVEL_METRIC} + }; + } + + @Test + public void toMeasure_should_not_loose_decimals_of_float_values() { + MetricImpl metric = new MetricImpl("42", "double", "name", Metric.MetricType.FLOAT, 5, null, false, false); + ProjectMeasureDto projectMeasureDto = new ProjectMeasureDto() + .setValue(0.12345); + + Optional measure = toMeasure(projectMeasureDto, metric); + + assertThat(measure.get().getDoubleValue()).isEqualTo(0.12345, Offset.offset(0.000001)); + } +} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/component/BranchDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/component/BranchDaoIT.java index 1b5a45eabb2..3240684ee32 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/component/BranchDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/component/BranchDaoIT.java @@ -131,7 +131,7 @@ class BranchDaoIT { MetricDto qg = db.measures().insertMetric(m -> m.setKey(ALERT_STATUS_KEY)); SnapshotDto analysis = db.components().insertSnapshot(dto); - db.measures().insertMeasure(dto, analysis, qg, pm -> pm.setData("OK")); + db.measures().insertProjectMeasure(dto, analysis, qg, pm -> pm.setData("OK")); var branchMeasures = underTest.selectBranchMeasuresWithCaycMetric(dbSession); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/measure/MeasureDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/measure/MeasureDaoIT.java deleted file mode 100644 index 7fd4c41144d..00000000000 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/measure/MeasureDaoIT.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.measure; - -import java.util.List; -import java.util.Optional; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.utils.System2; -import org.sonar.core.util.Uuids; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.SnapshotDto; -import org.sonar.db.component.SnapshotTesting; -import org.sonar.db.metric.MetricDto; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.utils.DateUtils.parseDate; -import static org.sonar.db.component.ComponentTesting.newDirectory; -import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.db.component.SnapshotTesting.newAnalysis; - -class MeasureDaoIT { - - private MetricDto coverage; - private MetricDto complexity; - private MetricDto ncloc; - - @RegisterExtension - private final DbTester db = DbTester.create(System2.INSTANCE); - private final DbClient dbClient = db.getDbClient(); - private final DbSession dbSession = db.getSession(); - private final MeasureDao underTest = db.getDbClient().measureDao(); - - @BeforeEach - void before() { - coverage = db.measures().insertMetric(m -> m.setKey("coverage")); - complexity = db.measures().insertMetric(m -> m.setKey("complexity")); - ncloc = db.measures().insertMetric(m -> m.setKey("ncloc")); - db.measures().insertMetric(m -> m.setKey("ncloc_language_distribution")); - } - - @Test - void test_selectLastMeasure() { - MetricDto metric = db.measures().insertMetric(); - ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - SnapshotDto lastAnalysis = insertAnalysis(project.uuid(), true); - SnapshotDto pastAnalysis = insertAnalysis(project.uuid(), false); - - MeasureDto pastMeasure = MeasureTesting.newMeasureDto(metric, file, pastAnalysis); - MeasureDto lastMeasure = MeasureTesting.newMeasureDto(metric, file, lastAnalysis); - underTest.insert(db.getSession(), pastMeasure); - underTest.insert(db.getSession(), lastMeasure); - - MeasureDto selected = underTest.selectLastMeasure(db.getSession(), file.uuid(), metric.getKey()).get(); - assertThat(selected).isEqualToComparingFieldByField(lastMeasure); - - assertThat(underTest.selectLastMeasure(dbSession, "_missing_", metric.getKey())).isEmpty(); - assertThat(underTest.selectLastMeasure(dbSession, file.uuid(), "_missing_")).isEmpty(); - assertThat(underTest.selectLastMeasure(dbSession, "_missing_", "_missing_")).isEmpty(); - } - - @Test - void test_selectMeasure() { - MetricDto metric = db.measures().insertMetric(); - ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - SnapshotDto lastAnalysis = insertAnalysis(project.uuid(), true); - SnapshotDto pastAnalysis = insertAnalysis(project.uuid(), false); - - MeasureDto pastMeasure = MeasureTesting.newMeasureDto(metric, file, pastAnalysis); - MeasureDto lastMeasure = MeasureTesting.newMeasureDto(metric, file, lastAnalysis); - underTest.insert(db.getSession(), pastMeasure); - underTest.insert(db.getSession(), lastMeasure); - - assertThat(underTest.selectMeasure(db.getSession(), lastAnalysis.getUuid(), file.uuid(), metric.getKey()).get()) - .isEqualToComparingFieldByField(lastMeasure); - - assertThat(underTest.selectMeasure(db.getSession(), pastAnalysis.getUuid(), file.uuid(), metric.getKey()).get()) - .isEqualToComparingFieldByField(pastMeasure); - - assertThat(underTest.selectMeasure(db.getSession(), "_missing_", file.uuid(), metric.getKey())).isEmpty(); - assertThat(underTest.selectMeasure(db.getSession(), pastAnalysis.getUuid(), "_missing_", metric.getKey())).isEmpty(); - assertThat(underTest.selectMeasure(db.getSession(), pastAnalysis.getUuid(), file.uuid(), "_missing_")).isEmpty(); - } - - @Test - void test_selects() { - ComponentDto project1 = db.components().insertPrivateProject().getMainBranchComponent(); - ComponentDto dir = db.components().insertComponent(newDirectory(project1, "path")); - db.components().insertComponent(newFileDto(dir).setUuid("C1")); - db.components().insertComponent(newFileDto(dir).setUuid("C2")); - SnapshotDto lastAnalysis = insertAnalysis(project1.uuid(), true); - SnapshotDto pastAnalysis = insertAnalysis(project1.uuid(), false); - - ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent(); - SnapshotDto project2LastAnalysis = insertAnalysis(project2.uuid(), true); - - // project 1 - insertMeasure("P1_M1", lastAnalysis.getUuid(), project1.uuid(), ncloc.getUuid()); - insertMeasure("P1_M2", lastAnalysis.getUuid(), project1.uuid(), coverage.getUuid()); - insertMeasure("P1_M3", pastAnalysis.getUuid(), project1.uuid(), ncloc.getUuid()); - // project 2 - insertMeasure("P2_M1", project2LastAnalysis.getUuid(), project2.uuid(), ncloc.getUuid()); - insertMeasure("P2_M2", project2LastAnalysis.getUuid(), project2.uuid(), coverage.getUuid()); - // component C1 - insertMeasure("M1", pastAnalysis.getUuid(), "C1", ncloc.getUuid()); - insertMeasure("M2", lastAnalysis.getUuid(), "C1", ncloc.getUuid()); - insertMeasure("M3", lastAnalysis.getUuid(), "C1", coverage.getUuid()); - // component C2 - insertMeasure("M6", lastAnalysis.getUuid(), "C2", ncloc.getUuid()); - db.commit(); - - verifyNoMeasure("C1", ncloc.getKey(), "invalid_analysis"); - verifyNoMeasure("C1", "INVALID_KEY"); - verifyNoMeasure("C1", "INVALID_KEY", pastAnalysis.getUuid()); - verifyNoMeasure("MISSING_COMPONENT", ncloc.getKey()); - verifyNoMeasure("MISSING_COMPONENT", ncloc.getKey(), pastAnalysis.getUuid()); - - // ncloc measure of component C1 of last analysis - verifyMeasure("C1", ncloc.getKey(), "M2"); - // ncloc measure of component C1 of non last analysis - verifyMeasure("C1", ncloc.getKey(), pastAnalysis.getUuid(), "M1"); - // ncloc measure of component C1 of last analysis by UUID - verifyMeasure("C1", ncloc.getKey(), lastAnalysis.getUuid(), "M2"); - - // missing measure of component C1 of last analysis - verifyNoMeasure("C1", complexity.getKey()); - // missing measure of component C1 of non last analysis - verifyNoMeasure("C1", complexity.getKey(), pastAnalysis.getUuid()); - // missing measure of component C1 of last analysis by UUID - verifyNoMeasure("C1", complexity.getKey(), lastAnalysis.getUuid()); - - // projects measures of last analysis - verifyMeasure(project1.uuid(), ncloc.getKey(), "P1_M1"); - - // projects measures of none last analysis - verifyMeasure(project1.uuid(), ncloc.getKey(), pastAnalysis.getUuid(), "P1_M3"); - } - - @Test - void select_past_measures_with_several_analyses() { - ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - long lastAnalysisDate = parseDate("2017-01-25").getTime(); - long previousAnalysisDate = lastAnalysisDate - 10_000_000_000L; - long oldAnalysisDate = lastAnalysisDate - 100_000_000_000L; - SnapshotDto lastAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(project).setCreatedAt(lastAnalysisDate)); - SnapshotDto pastAnalysis = dbClient.snapshotDao().insert(dbSession, - newAnalysis(project).setCreatedAt(previousAnalysisDate).setLast(false)); - dbClient.snapshotDao().insert(dbSession, newAnalysis(project).setCreatedAt(oldAnalysisDate).setLast(false)); - db.commit(); - - // project - insertMeasure("PROJECT_M1", lastAnalysis.getUuid(), project.uuid(), ncloc.getUuid()); - insertMeasure("PROJECT_M2", pastAnalysis.getUuid(), project.uuid(), ncloc.getUuid()); - insertMeasure("PROJECT_M3", "OLD_ANALYSIS_UUID", project.uuid(), ncloc.getUuid()); - db.commit(); - - // Measures of project for last and previous analyses - List result = underTest.selectPastMeasures(db.getSession(), - new PastMeasureQuery(project.uuid(), singletonList(ncloc.getUuid()), previousAnalysisDate, lastAnalysisDate + 1_000L)); - - assertThat(result).hasSize(2).extracting(MeasureDto::getData).containsOnly("PROJECT_M1", "PROJECT_M2"); - } - - private void verifyMeasure(String componentUuid, String metricKey, String analysisUuid, String value) { - Optional measure = underTest.selectMeasure(db.getSession(), analysisUuid, componentUuid, metricKey); - assertThat(measure.map(MeasureDto::getData)).contains(value); - assertThat(measure.map(MeasureDto::getUuid)).isNotEmpty(); - } - - private void verifyMeasure(String componentUuid, String metricKey, String value) { - Optional measure = underTest.selectLastMeasure(db.getSession(), componentUuid, metricKey); - assertThat(measure.map(MeasureDto::getData)).contains(value); - assertThat(measure.map(MeasureDto::getUuid)).isNotEmpty(); - } - - private void verifyNoMeasure(String componentUuid, String metricKey, String analysisUuid) { - assertThat(underTest.selectMeasure(db.getSession(), analysisUuid, componentUuid, metricKey)).isEmpty(); - } - - private void verifyNoMeasure(String componentUuid, String metricKey) { - assertThat(underTest.selectLastMeasure(db.getSession(), componentUuid, metricKey)).isEmpty(); - } - - private void insertMeasure(String value, String analysisUuid, String componentUuid, String metricUuid) { - MeasureDto measure = MeasureTesting.newMeasure() - .setAnalysisUuid(analysisUuid) - .setComponentUuid(componentUuid) - .setMetricUuid(metricUuid) - // as ids can't be forced when inserting measures, the field "data" - // is used to store a virtual value. It is used then in assertions. - .setData(value); - db.getDbClient().measureDao().insert(db.getSession(), measure); - } - - private SnapshotDto insertAnalysis(String projectUuid, boolean isLast) { - return db.getDbClient().snapshotDao().insert(db.getSession(), SnapshotTesting.newSnapshot() - .setUuid(Uuids.createFast()) - .setRootComponentUuid(projectUuid) - .setLast(isLast)); - } - -} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/measure/ProjectMeasureDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/measure/ProjectMeasureDaoIT.java new file mode 100644 index 00000000000..1749fd7ebc9 --- /dev/null +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/measure/ProjectMeasureDaoIT.java @@ -0,0 +1,226 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.measure; + +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.api.utils.System2; +import org.sonar.core.util.Uuids; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.SnapshotDto; +import org.sonar.db.component.SnapshotTesting; +import org.sonar.db.metric.MetricDto; + +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.utils.DateUtils.parseDate; +import static org.sonar.db.component.ComponentTesting.newDirectory; +import static org.sonar.db.component.ComponentTesting.newFileDto; +import static org.sonar.db.component.SnapshotTesting.newAnalysis; + +class ProjectMeasureDaoIT { + + private MetricDto coverage; + private MetricDto complexity; + private MetricDto ncloc; + + @RegisterExtension + private final DbTester db = DbTester.create(System2.INSTANCE); + private final DbClient dbClient = db.getDbClient(); + private final DbSession dbSession = db.getSession(); + private final ProjectMeasureDao underTest = db.getDbClient().projectMeasureDao(); + + @BeforeEach + void before() { + coverage = db.measures().insertMetric(m -> m.setKey("coverage")); + complexity = db.measures().insertMetric(m -> m.setKey("complexity")); + ncloc = db.measures().insertMetric(m -> m.setKey("ncloc")); + db.measures().insertMetric(m -> m.setKey("ncloc_language_distribution")); + } + + @Test + void test_selectLastMeasure() { + MetricDto metric = db.measures().insertMetric(); + ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); + ComponentDto file = db.components().insertComponent(newFileDto(project)); + SnapshotDto lastAnalysis = insertAnalysis(project.uuid(), true); + SnapshotDto pastAnalysis = insertAnalysis(project.uuid(), false); + + ProjectMeasureDto pastMeasure = MeasureTesting.newProjectMeasureDto(metric, file, pastAnalysis); + ProjectMeasureDto lastMeasure = MeasureTesting.newProjectMeasureDto(metric, file, lastAnalysis); + underTest.insert(db.getSession(), pastMeasure); + underTest.insert(db.getSession(), lastMeasure); + + ProjectMeasureDto selected = underTest.selectLastMeasure(db.getSession(), file.uuid(), metric.getKey()).get(); + assertThat(selected).isEqualToComparingFieldByField(lastMeasure); + + assertThat(underTest.selectLastMeasure(dbSession, "_missing_", metric.getKey())).isEmpty(); + assertThat(underTest.selectLastMeasure(dbSession, file.uuid(), "_missing_")).isEmpty(); + assertThat(underTest.selectLastMeasure(dbSession, "_missing_", "_missing_")).isEmpty(); + } + + @Test + void test_selectMeasure() { + MetricDto metric = db.measures().insertMetric(); + ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); + ComponentDto file = db.components().insertComponent(newFileDto(project)); + SnapshotDto lastAnalysis = insertAnalysis(project.uuid(), true); + SnapshotDto pastAnalysis = insertAnalysis(project.uuid(), false); + + ProjectMeasureDto pastMeasure = MeasureTesting.newProjectMeasureDto(metric, file, pastAnalysis); + ProjectMeasureDto lastMeasure = MeasureTesting.newProjectMeasureDto(metric, file, lastAnalysis); + underTest.insert(db.getSession(), pastMeasure); + underTest.insert(db.getSession(), lastMeasure); + + assertThat(underTest.selectMeasure(db.getSession(), lastAnalysis.getUuid(), file.uuid(), metric.getKey()).get()) + .isEqualToComparingFieldByField(lastMeasure); + + assertThat(underTest.selectMeasure(db.getSession(), pastAnalysis.getUuid(), file.uuid(), metric.getKey()).get()) + .isEqualToComparingFieldByField(pastMeasure); + + assertThat(underTest.selectMeasure(db.getSession(), "_missing_", file.uuid(), metric.getKey())).isEmpty(); + assertThat(underTest.selectMeasure(db.getSession(), pastAnalysis.getUuid(), "_missing_", metric.getKey())).isEmpty(); + assertThat(underTest.selectMeasure(db.getSession(), pastAnalysis.getUuid(), file.uuid(), "_missing_")).isEmpty(); + } + + @Test + void test_selects() { + ComponentDto project1 = db.components().insertPrivateProject().getMainBranchComponent(); + ComponentDto dir = db.components().insertComponent(newDirectory(project1, "path")); + db.components().insertComponent(newFileDto(dir).setUuid("C1")); + db.components().insertComponent(newFileDto(dir).setUuid("C2")); + SnapshotDto lastAnalysis = insertAnalysis(project1.uuid(), true); + SnapshotDto pastAnalysis = insertAnalysis(project1.uuid(), false); + + ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent(); + SnapshotDto project2LastAnalysis = insertAnalysis(project2.uuid(), true); + + // project 1 + insertMeasure("P1_M1", lastAnalysis.getUuid(), project1.uuid(), ncloc.getUuid()); + insertMeasure("P1_M2", lastAnalysis.getUuid(), project1.uuid(), coverage.getUuid()); + insertMeasure("P1_M3", pastAnalysis.getUuid(), project1.uuid(), ncloc.getUuid()); + // project 2 + insertMeasure("P2_M1", project2LastAnalysis.getUuid(), project2.uuid(), ncloc.getUuid()); + insertMeasure("P2_M2", project2LastAnalysis.getUuid(), project2.uuid(), coverage.getUuid()); + // component C1 + insertMeasure("M1", pastAnalysis.getUuid(), "C1", ncloc.getUuid()); + insertMeasure("M2", lastAnalysis.getUuid(), "C1", ncloc.getUuid()); + insertMeasure("M3", lastAnalysis.getUuid(), "C1", coverage.getUuid()); + // component C2 + insertMeasure("M6", lastAnalysis.getUuid(), "C2", ncloc.getUuid()); + db.commit(); + + verifyNoMeasure("C1", ncloc.getKey(), "invalid_analysis"); + verifyNoMeasure("C1", "INVALID_KEY"); + verifyNoMeasure("C1", "INVALID_KEY", pastAnalysis.getUuid()); + verifyNoMeasure("MISSING_COMPONENT", ncloc.getKey()); + verifyNoMeasure("MISSING_COMPONENT", ncloc.getKey(), pastAnalysis.getUuid()); + + // ncloc measure of component C1 of last analysis + verifyMeasure("C1", ncloc.getKey(), "M2"); + // ncloc measure of component C1 of non last analysis + verifyMeasure("C1", ncloc.getKey(), pastAnalysis.getUuid(), "M1"); + // ncloc measure of component C1 of last analysis by UUID + verifyMeasure("C1", ncloc.getKey(), lastAnalysis.getUuid(), "M2"); + + // missing measure of component C1 of last analysis + verifyNoMeasure("C1", complexity.getKey()); + // missing measure of component C1 of non last analysis + verifyNoMeasure("C1", complexity.getKey(), pastAnalysis.getUuid()); + // missing measure of component C1 of last analysis by UUID + verifyNoMeasure("C1", complexity.getKey(), lastAnalysis.getUuid()); + + // projects measures of last analysis + verifyMeasure(project1.uuid(), ncloc.getKey(), "P1_M1"); + + // projects measures of none last analysis + verifyMeasure(project1.uuid(), ncloc.getKey(), pastAnalysis.getUuid(), "P1_M3"); + } + + @Test + void select_past_measures_with_several_analyses() { + ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); + long lastAnalysisDate = parseDate("2017-01-25").getTime(); + long previousAnalysisDate = lastAnalysisDate - 10_000_000_000L; + long oldAnalysisDate = lastAnalysisDate - 100_000_000_000L; + SnapshotDto lastAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(project).setCreatedAt(lastAnalysisDate)); + SnapshotDto pastAnalysis = dbClient.snapshotDao().insert(dbSession, + newAnalysis(project).setCreatedAt(previousAnalysisDate).setLast(false)); + dbClient.snapshotDao().insert(dbSession, newAnalysis(project).setCreatedAt(oldAnalysisDate).setLast(false)); + db.commit(); + + // project + insertMeasure("PROJECT_M1", lastAnalysis.getUuid(), project.uuid(), ncloc.getUuid()); + insertMeasure("PROJECT_M2", pastAnalysis.getUuid(), project.uuid(), ncloc.getUuid()); + insertMeasure("PROJECT_M3", "OLD_ANALYSIS_UUID", project.uuid(), ncloc.getUuid()); + db.commit(); + + // Measures of project for last and previous analyses + List result = underTest.selectPastMeasures(db.getSession(), + new PastMeasureQuery(project.uuid(), singletonList(ncloc.getUuid()), previousAnalysisDate, lastAnalysisDate + 1_000L)); + + assertThat(result).hasSize(2).extracting(ProjectMeasureDto::getData).containsOnly("PROJECT_M1", "PROJECT_M2"); + } + + private void verifyMeasure(String componentUuid, String metricKey, String analysisUuid, String value) { + Optional measure = underTest.selectMeasure(db.getSession(), analysisUuid, componentUuid, metricKey); + assertThat(measure.map(ProjectMeasureDto::getData)).contains(value); + assertThat(measure.map(ProjectMeasureDto::getUuid)).isNotEmpty(); + } + + private void verifyMeasure(String componentUuid, String metricKey, String value) { + Optional measure = underTest.selectLastMeasure(db.getSession(), componentUuid, metricKey); + assertThat(measure.map(ProjectMeasureDto::getData)).contains(value); + assertThat(measure.map(ProjectMeasureDto::getUuid)).isNotEmpty(); + } + + private void verifyNoMeasure(String componentUuid, String metricKey, String analysisUuid) { + assertThat(underTest.selectMeasure(db.getSession(), analysisUuid, componentUuid, metricKey)).isEmpty(); + } + + private void verifyNoMeasure(String componentUuid, String metricKey) { + assertThat(underTest.selectLastMeasure(db.getSession(), componentUuid, metricKey)).isEmpty(); + } + + private void insertMeasure(String value, String analysisUuid, String componentUuid, String metricUuid) { + ProjectMeasureDto measure = MeasureTesting.newProjectMeasure() + .setAnalysisUuid(analysisUuid) + .setComponentUuid(componentUuid) + .setMetricUuid(metricUuid) + // as ids can't be forced when inserting measures, the field "data" + // is used to store a virtual value. It is used then in assertions. + .setData(value); + db.getDbClient().projectMeasureDao().insert(db.getSession(), measure); + } + + private SnapshotDto insertAnalysis(String projectUuid, boolean isLast) { + return db.getDbClient().snapshotDao().insert(db.getSession(), SnapshotTesting.newSnapshot() + .setUuid(Uuids.createFast()) + .setRootComponentUuid(projectUuid) + .setLast(isLast)); + } + +} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeCommandsIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeCommandsIT.java index 818fd758235..0653bb15b9d 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeCommandsIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeCommandsIT.java @@ -318,10 +318,10 @@ class PurgeCommandsIT { int count = 5; Stream.of(metric1, metric2) .forEach(metric -> IntStream.range(0, count).forEach(i -> { - dbTester.measures().insertMeasure(projectOrView, analysis1, metric); - dbTester.measures().insertMeasure(projectOrView, analysis2, metric); - dbTester.measures().insertMeasure(otherProject, otherAnalysis1, metric); - dbTester.measures().insertMeasure(otherProject, otherAnalysis2, metric); + dbTester.measures().insertProjectMeasure(projectOrView, analysis1, metric); + dbTester.measures().insertProjectMeasure(projectOrView, analysis2, metric); + dbTester.measures().insertProjectMeasure(otherProject, otherAnalysis1, metric); + dbTester.measures().insertProjectMeasure(otherProject, otherAnalysis2, metric); })); underTest.deleteAnalyses(projectOrView.uuid()); @@ -457,8 +457,8 @@ class PurgeCommandsIT { int count = 5; Stream.of(metric1, metric2) .forEach(metric -> IntStream.range(0, count).forEach(i -> { - dbTester.measures().insertMeasure(projectOrView, analysis, metric); - dbTester.measures().insertMeasure(projectOrView, otherAnalysis, metric); + dbTester.measures().insertProjectMeasure(projectOrView, analysis, metric); + dbTester.measures().insertProjectMeasure(projectOrView, otherAnalysis, metric); })); underTest.deleteAnalyses(singletonList(analysis.getUuid())); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java index 2bef9d30cc9..489aaf8b2e8 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java @@ -78,7 +78,7 @@ import org.sonar.db.issue.AnticipatedTransitionDto; import org.sonar.db.issue.IssueChangeDto; import org.sonar.db.issue.IssueDto; import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.metric.MetricDto; import org.sonar.db.newcodeperiod.NewCodePeriodDto; import org.sonar.db.newcodeperiod.NewCodePeriodType; @@ -668,7 +668,7 @@ project.getProjectDto().getUuid()), PurgeListener.EMPTY, new PurgeProfiler()); MetricDto metric = db.measures().insertMetric(); ProjectData project = db.components().insertPrivateProject(); BranchDto mainBranch = db.getDbClient().branchDao().selectByUuid(db.getSession(), project.getMainBranchDto().getUuid()).get(); - RuleDto rule = db.rules().insert(); + db.rules().insert(); ProjectData app = db.components().insertPrivateApplication(); BranchDto appBranch = db.components().insertProjectBranch(app.getProjectDto()); @@ -680,12 +680,12 @@ project.getProjectDto().getUuid()), PurgeListener.EMPTY, new PurgeProfiler()); SnapshotDto otherAppAnalysis = db.components().insertSnapshot(otherApp.getProjectDto()); SnapshotDto otherAppBranchAnalysis = db.components().insertSnapshot(otherAppBranch); - MeasureDto appMeasure = db.measures().insertMeasure(app.getMainBranchComponent(), appAnalysis, metric); + db.measures().insertProjectMeasure(app.getMainBranchComponent(), appAnalysis, metric); ComponentDto appBranchComponent = db.components().getComponentDto(appBranch); - MeasureDto appBranchMeasure = db.measures().insertMeasure(appBranchComponent, appBranchAnalysis, metric); - MeasureDto otherAppMeasure = db.measures().insertMeasure(otherApp.getMainBranchComponent(), otherAppAnalysis, metric); + db.measures().insertProjectMeasure(appBranchComponent, appBranchAnalysis, metric); + ProjectMeasureDto otherAppMeasure = db.measures().insertProjectMeasure(otherApp.getMainBranchComponent(), otherAppAnalysis, metric); ComponentDto otherAppBranchComponent = db.components().getComponentDto(otherAppBranch); - MeasureDto otherAppBranchMeasure = db.measures().insertMeasure(otherAppBranchComponent, otherAppBranchAnalysis, metric); + ProjectMeasureDto otherAppBranchMeasure = db.measures().insertProjectMeasure(otherAppBranchComponent, otherAppBranchAnalysis, metric); db.components().addApplicationProject(app.getProjectDto(), project.getProjectDto()); db.components().addApplicationProject(otherApp.getProjectDto(), project.getProjectDto()); @@ -714,7 +714,7 @@ mainBranch); MetricDto metric = db.measures().insertMetric(); ProjectData project = db.components().insertPrivateProject(); BranchDto projectBranch = db.getDbClient().branchDao().selectByUuid(db.getSession(), project.getMainBranchDto().getUuid()).get(); - RuleDto rule = db.rules().insert(); + db.rules().insert(); ProjectData app = db.components().insertPrivateApplication(); BranchDto appBranch = db.components().insertProjectBranch(app.getProjectDto()); @@ -726,12 +726,12 @@ mainBranch); SnapshotDto otherAppAnalysis = db.components().insertSnapshot(otherApp.getProjectDto()); SnapshotDto otherAppBranchAnalysis = db.components().insertSnapshot(otherAppBranch); - MeasureDto appMeasure = db.measures().insertMeasure(app.getMainBranchComponent(), appAnalysis, metric); + ProjectMeasureDto appMeasure = db.measures().insertProjectMeasure(app.getMainBranchComponent(), appAnalysis, metric); ComponentDto appBranchComponent = db.components().getComponentDto(appBranch); - MeasureDto appBranchMeasure = db.measures().insertMeasure(appBranchComponent, appBranchAnalysis, metric); - MeasureDto otherAppMeasure = db.measures().insertMeasure(otherApp.getMainBranchComponent(), otherAppAnalysis, metric); + db.measures().insertProjectMeasure(appBranchComponent, appBranchAnalysis, metric); + ProjectMeasureDto otherAppMeasure = db.measures().insertProjectMeasure(otherApp.getMainBranchComponent(), otherAppAnalysis, metric); ComponentDto otherAppBranchComponent = db.components().getComponentDto(otherAppBranch); - MeasureDto otherAppBranchMeasure = db.measures().insertMeasure(otherAppBranchComponent, otherAppBranchAnalysis, metric); + ProjectMeasureDto otherAppBranchMeasure = db.measures().insertProjectMeasure(otherAppBranchComponent, otherAppBranchAnalysis, metric); db.components().addApplicationProject(app.getProjectDto(), project.getProjectDto()); db.components().addApplicationProject(otherApp.getProjectDto(), project.getProjectDto()); @@ -2027,7 +2027,7 @@ oldCreationDate)); } private void insertMeasureFor(ComponentDto... components) { - Arrays.stream(components).forEach(componentDto -> db.getDbClient().measureDao().insert(dbSession, new MeasureDto() + Arrays.stream(components).forEach(componentDto -> db.getDbClient().projectMeasureDao().insert(dbSession, new ProjectMeasureDto() .setMetricUuid(randomAlphabetic(3)) .setComponentUuid(componentDto.uuid()) .setAnalysisUuid(randomAlphabetic(3)))); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java index bb7b126d088..fb0ac071f4b 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java @@ -48,7 +48,7 @@ import org.sonar.db.issue.IssueChangeDao; import org.sonar.db.issue.IssueDao; import org.sonar.db.issue.IssueFixedDao; import org.sonar.db.measure.LiveMeasureDao; -import org.sonar.db.measure.MeasureDao; +import org.sonar.db.measure.ProjectMeasureDao; import org.sonar.db.metric.MetricDao; import org.sonar.db.newcodeperiod.NewCodePeriodDao; import org.sonar.db.notification.NotificationQueueDao; @@ -148,7 +148,7 @@ public class DaoModule extends Module { IssueDao.class, IssueFixedDao.class, LiveMeasureDao.class, - MeasureDao.class, + ProjectMeasureDao.class, MetricDao.class, NewCodePeriodDao.class, NotificationQueueDao.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java index 8f68429cbb0..598d3663e1c 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java @@ -48,7 +48,7 @@ import org.sonar.db.issue.IssueChangeDao; import org.sonar.db.issue.IssueDao; import org.sonar.db.issue.IssueFixedDao; import org.sonar.db.measure.LiveMeasureDao; -import org.sonar.db.measure.MeasureDao; +import org.sonar.db.measure.ProjectMeasureDao; import org.sonar.db.metric.MetricDao; import org.sonar.db.newcodeperiod.NewCodePeriodDao; import org.sonar.db.notification.NotificationQueueDao; @@ -126,7 +126,7 @@ public class DbClient { private final SnapshotDao snapshotDao; private final ComponentDao componentDao; private final ComponentKeyUpdaterDao componentKeyUpdaterDao; - private final MeasureDao measureDao; + private final ProjectMeasureDao projectMeasureDao; private final UserDao userDao; private final UserGroupDao userGroupDao; private final UserTokenDao userTokenDao; @@ -220,7 +220,7 @@ public class DbClient { snapshotDao = getDao(map, SnapshotDao.class); componentDao = getDao(map, ComponentDao.class); componentKeyUpdaterDao = getDao(map, ComponentKeyUpdaterDao.class); - measureDao = getDao(map, MeasureDao.class); + projectMeasureDao = getDao(map, ProjectMeasureDao.class); userDao = getDao(map, UserDao.class); userGroupDao = getDao(map, UserGroupDao.class); userTokenDao = getDao(map, UserTokenDao.class); @@ -389,8 +389,8 @@ public class DbClient { return componentKeyUpdaterDao; } - public MeasureDao measureDao() { - return measureDao; + public ProjectMeasureDao projectMeasureDao() { + return projectMeasureDao; } public UserDao userDao() { @@ -647,4 +647,3 @@ public class DbClient { return projectExportDao; } } - diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java index e14f8adac8a..543c465f450 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java @@ -83,8 +83,8 @@ import org.sonar.db.issue.NewCodeReferenceIssueDto; import org.sonar.db.issue.PrIssueDto; import org.sonar.db.measure.LargestBranchNclocDto; import org.sonar.db.measure.LiveMeasureMapper; -import org.sonar.db.measure.MeasureDto; -import org.sonar.db.measure.MeasureMapper; +import org.sonar.db.measure.ProjectMeasureDto; +import org.sonar.db.measure.ProjectMeasureMapper; import org.sonar.db.measure.ProjectLocDistributionDto; import org.sonar.db.metric.MetricMapper; import org.sonar.db.newcodeperiod.NewCodePeriodMapper; @@ -226,7 +226,7 @@ public class MyBatis { confBuilder.loadAlias("Impact", ImpactDto.class); confBuilder.loadAlias("Issue", IssueDto.class); confBuilder.loadAlias("NewCodeReferenceIssue", NewCodeReferenceIssueDto.class); - confBuilder.loadAlias("Measure", MeasureDto.class); + confBuilder.loadAlias("ProjectMeasure", ProjectMeasureDto.class); confBuilder.loadAlias("LargestBranchNclocDto", LargestBranchNclocDto.class); confBuilder.loadAlias("NotificationQueue", NotificationQueueDto.class); confBuilder.loadAlias("PermissionTemplateCharacteristic", PermissionTemplateCharacteristicDto.class); @@ -304,7 +304,7 @@ public class MyBatis { IssueChangeMapper.class, IssueMapper.class, IssueFixedMapper.class, - MeasureMapper.class, + ProjectMeasureMapper.class, MetricMapper.class, NewCodePeriodMapper.class, NotificationQueueMapper.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java deleted file mode 100644 index db2407623df..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.measure; - -import com.google.common.collect.Lists; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Dao; -import org.sonar.db.DbSession; - -public class MeasureDao implements Dao { - - private final UuidFactory uuidFactory; - - public MeasureDao(UuidFactory uuidFactory) { - this.uuidFactory = uuidFactory; - } - - public Optional selectLastMeasure(DbSession dbSession, String componentUuid, String metricKey) { - return Optional.ofNullable(mapper(dbSession).selectLastMeasure(componentUuid, metricKey)); - } - - public Optional selectMeasure(DbSession dbSession, String analysisUuid, String componentUuid, String metricKey) { - return Optional.ofNullable(mapper(dbSession).selectMeasure(analysisUuid, componentUuid, metricKey)); - } - - /** - * Select measures of: - * - one component - * - for a list of metrics - * - with analysis from a date (inclusive) - optional - * - with analysis to a date (exclusive) - optional - * - * If no constraints on dates, all the history is returned - */ - public List selectPastMeasures(DbSession dbSession, PastMeasureQuery query) { - return mapper(dbSession).selectPastMeasuresOnSeveralAnalyses(query); - } - - public void insert(DbSession session, MeasureDto measureDto) { - measureDto.setUuid(uuidFactory.create()); - mapper(session).insert(measureDto); - } - - public void insert(DbSession session, Collection items) { - for (MeasureDto item : items) { - item.setUuid(uuidFactory.create()); - insert(session, item); - } - } - - public void insert(DbSession session, MeasureDto item, MeasureDto... others) { - insert(session, Lists.asList(item, others)); - } - - private static MeasureMapper mapper(DbSession session) { - return session.getMapper(MeasureMapper.class); - } - -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDto.java deleted file mode 100644 index 0c70d6143ba..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDto.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.measure; - -import com.google.common.base.MoreObjects; -import java.nio.charset.StandardCharsets; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; - -public class MeasureDto { - private static final int MAX_TEXT_VALUE_LENGTH = 4000; - - private String uuid; - private Double value; - private String textValue; - private byte[] dataValue; - private String alertStatus; - private String alertText; - private String componentUuid; - private String analysisUuid; - private String metricUuid; - - public String getUuid() { - return uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - @CheckForNull - public Double getValue() { - return value; - } - - public MeasureDto setValue(@Nullable Double value) { - this.value = value; - return this; - } - - public String getComponentUuid() { - return componentUuid; - } - - public MeasureDto setComponentUuid(String s) { - this.componentUuid = s; - return this; - } - - @CheckForNull - public String getData() { - if (dataValue != null) { - return new String(dataValue, StandardCharsets.UTF_8); - } - return textValue; - } - - public MeasureDto setData(@Nullable String data) { - if (data == null) { - this.textValue = null; - this.dataValue = null; - } else if (data.length() > MAX_TEXT_VALUE_LENGTH) { - this.textValue = null; - this.dataValue = data.getBytes(StandardCharsets.UTF_8); - } else { - this.textValue = data; - this.dataValue = null; - } - - return this; - } - - @CheckForNull - public String getAlertStatus() { - return alertStatus; - } - - public MeasureDto setAlertStatus(@Nullable String alertStatus) { - this.alertStatus = alertStatus; - return this; - } - - @CheckForNull - public String getAlertText() { - return alertText; - } - - public MeasureDto setAlertText(@Nullable String alertText) { - this.alertText = alertText; - return this; - } - - public String getMetricUuid() { - return metricUuid; - } - - public MeasureDto setMetricUuid(String metricUuid) { - this.metricUuid = metricUuid; - return this; - } - - public String getAnalysisUuid() { - return analysisUuid; - } - - public MeasureDto setAnalysisUuid(String s) { - this.analysisUuid = s; - return this; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("value", value) - .add("textValue", textValue) - .add("dataValue", dataValue) - .add("alertStatus", alertStatus) - .add("alertText", alertText) - .add("componentUuid", componentUuid) - .add("analysisUuid", analysisUuid) - .add("metricUuid", metricUuid) - .toString(); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java deleted file mode 100644 index de9e823f186..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.measure; - -import java.util.List; -import javax.annotation.CheckForNull; -import org.apache.ibatis.annotations.Param; - -public interface MeasureMapper { - - @CheckForNull - MeasureDto selectLastMeasure( - @Param("componentUuid") String componentUuid, - @Param("metricKey") String metricKey - ); - - @CheckForNull - MeasureDto selectMeasure( - @Param("analysisUuid") String analysisUuid, - @Param("componentUuid") String componentUuid, - @Param("metricKey") String metricKey - ); - - List selectPastMeasuresOnSeveralAnalyses(@Param("query") PastMeasureQuery query); - - void insert(MeasureDto measureDto); - -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/PastMeasureDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/PastMeasureDto.java deleted file mode 100644 index 71ec6f669aa..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/PastMeasureDto.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.measure; - -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; - -import static java.util.Objects.requireNonNull; - -public class PastMeasureDto { - - private String metricUuid; - - @CheckForNull - private Double value; - - public double getValue() { - requireNonNull(value); - return value; - } - - PastMeasureDto setValue(@Nullable Double value) { - this.value = value; - return this; - } - - public boolean hasValue() { - return value != null; - } - - public String getMetricUuid() { - return metricUuid; - } - - PastMeasureDto setMetricUuid(String i) { - this.metricUuid = i; - return this; - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasureDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasureDao.java new file mode 100644 index 00000000000..c0709a83cb4 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasureDao.java @@ -0,0 +1,79 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.measure; + +import com.google.common.collect.Lists; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import org.sonar.core.util.UuidFactory; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; + +public class ProjectMeasureDao implements Dao { + + private final UuidFactory uuidFactory; + + public ProjectMeasureDao(UuidFactory uuidFactory) { + this.uuidFactory = uuidFactory; + } + + public Optional selectLastMeasure(DbSession dbSession, String componentUuid, String metricKey) { + return Optional.ofNullable(mapper(dbSession).selectLastMeasure(componentUuid, metricKey)); + } + + public Optional selectMeasure(DbSession dbSession, String analysisUuid, String componentUuid, String metricKey) { + return Optional.ofNullable(mapper(dbSession).selectMeasure(analysisUuid, componentUuid, metricKey)); + } + + /** + * Select measures of: + * - one component + * - for a list of metrics + * - with analysis from a date (inclusive) - optional + * - with analysis to a date (exclusive) - optional + * + * If no constraints on dates, all the history is returned + */ + public List selectPastMeasures(DbSession dbSession, PastMeasureQuery query) { + return mapper(dbSession).selectPastMeasuresOnSeveralAnalyses(query); + } + + public void insert(DbSession session, ProjectMeasureDto projectMeasureDto) { + projectMeasureDto.setUuid(uuidFactory.create()); + mapper(session).insert(projectMeasureDto); + } + + public void insert(DbSession session, Collection items) { + for (ProjectMeasureDto item : items) { + item.setUuid(uuidFactory.create()); + insert(session, item); + } + } + + public void insert(DbSession session, ProjectMeasureDto item, ProjectMeasureDto... others) { + insert(session, Lists.asList(item, others)); + } + + private static ProjectMeasureMapper mapper(DbSession session) { + return session.getMapper(ProjectMeasureMapper.class); + } + +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasureDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasureDto.java new file mode 100644 index 00000000000..fe65d2929c3 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasureDto.java @@ -0,0 +1,145 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.measure; + +import com.google.common.base.MoreObjects; +import java.nio.charset.StandardCharsets; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +public class ProjectMeasureDto { + private static final int MAX_TEXT_VALUE_LENGTH = 4000; + + private String uuid; + private Double value; + private String textValue; + private byte[] dataValue; + private String alertStatus; + private String alertText; + private String componentUuid; + private String analysisUuid; + private String metricUuid; + + public ProjectMeasureDto() { + // empty constructor + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @CheckForNull + public Double getValue() { + return value; + } + + public ProjectMeasureDto setValue(@Nullable Double value) { + this.value = value; + return this; + } + + public String getComponentUuid() { + return componentUuid; + } + + public ProjectMeasureDto setComponentUuid(String s) { + this.componentUuid = s; + return this; + } + + @CheckForNull + public String getData() { + if (dataValue != null) { + return new String(dataValue, StandardCharsets.UTF_8); + } + return textValue; + } + + public ProjectMeasureDto setData(@Nullable String data) { + if (data == null) { + this.textValue = null; + this.dataValue = null; + } else if (data.length() > MAX_TEXT_VALUE_LENGTH) { + this.textValue = null; + this.dataValue = data.getBytes(StandardCharsets.UTF_8); + } else { + this.textValue = data; + this.dataValue = null; + } + + return this; + } + + @CheckForNull + public String getAlertStatus() { + return alertStatus; + } + + public ProjectMeasureDto setAlertStatus(@Nullable String alertStatus) { + this.alertStatus = alertStatus; + return this; + } + + @CheckForNull + public String getAlertText() { + return alertText; + } + + public ProjectMeasureDto setAlertText(@Nullable String alertText) { + this.alertText = alertText; + return this; + } + + public String getMetricUuid() { + return metricUuid; + } + + public ProjectMeasureDto setMetricUuid(String metricUuid) { + this.metricUuid = metricUuid; + return this; + } + + public String getAnalysisUuid() { + return analysisUuid; + } + + public ProjectMeasureDto setAnalysisUuid(String s) { + this.analysisUuid = s; + return this; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("value", value) + .add("textValue", textValue) + .add("dataValue", dataValue) + .add("alertStatus", alertStatus) + .add("alertText", alertText) + .add("componentUuid", componentUuid) + .add("analysisUuid", analysisUuid) + .add("metricUuid", metricUuid) + .toString(); + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasureMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasureMapper.java new file mode 100644 index 00000000000..4d59b61de3d --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasureMapper.java @@ -0,0 +1,45 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.measure; + +import java.util.List; +import javax.annotation.CheckForNull; +import org.apache.ibatis.annotations.Param; + +public interface ProjectMeasureMapper { + + @CheckForNull + ProjectMeasureDto selectLastMeasure( + @Param("componentUuid") String componentUuid, + @Param("metricKey") String metricKey + ); + + @CheckForNull + ProjectMeasureDto selectMeasure( + @Param("analysisUuid") String analysisUuid, + @Param("componentUuid") String componentUuid, + @Param("metricKey") String metricKey + ); + + List selectPastMeasuresOnSeveralAnalyses(@Param("query") PastMeasureQuery query); + + void insert(ProjectMeasureDto projectMeasureDto); + +} diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml deleted file mode 100644 index a864b092452..00000000000 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - pm.uuid as uuid, - pm.metric_uuid as metricUuid, - pm.component_uuid as componentUuid, - pm.analysis_uuid as analysisUuid, - pm.value as value, - pm.text_value as textValue, - pm.alert_status as alertStatus, - pm.alert_text as alertText, - pm.measure_data as dataValue - - - - - - - - inner join snapshots analysis on analysis.uuid = pm.analysis_uuid - - inner join metrics m on m.uuid = pm.metric_uuid - - - - - - - insert into project_measures ( - uuid, - value, - metric_uuid, - component_uuid, - analysis_uuid, - text_value, - alert_status, - alert_text, - measure_data) - VALUES ( - #{uuid, jdbcType=VARCHAR}, - #{value, jdbcType=DOUBLE}, - #{metricUuid, jdbcType=VARCHAR}, - #{componentUuid, jdbcType=VARCHAR}, - #{analysisUuid, jdbcType=VARCHAR}, - #{textValue, jdbcType=VARCHAR}, - #{alertStatus, jdbcType=VARCHAR}, - #{alertText, jdbcType=VARCHAR}, - #{dataValue, jdbcType=BINARY} - ) - - - diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/ProjectMeasureMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/ProjectMeasureMapper.xml new file mode 100644 index 00000000000..60831985ea4 --- /dev/null +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/ProjectMeasureMapper.xml @@ -0,0 +1,87 @@ + + + + + + + pm.uuid as uuid, + pm.metric_uuid as metricUuid, + pm.component_uuid as componentUuid, + pm.analysis_uuid as analysisUuid, + pm.value as value, + pm.text_value as textValue, + pm.alert_status as alertStatus, + pm.alert_text as alertText, + pm.measure_data as dataValue + + + + + + + + inner join snapshots analysis on analysis.uuid = pm.analysis_uuid + + inner join metrics m on m.uuid = pm.metric_uuid + + + + + + + insert into project_measures ( + uuid, + value, + metric_uuid, + component_uuid, + analysis_uuid, + text_value, + alert_status, + alert_text, + measure_data) + VALUES ( + #{uuid, jdbcType=VARCHAR}, + #{value, jdbcType=DOUBLE}, + #{metricUuid, jdbcType=VARCHAR}, + #{componentUuid, jdbcType=VARCHAR}, + #{analysisUuid, jdbcType=VARCHAR}, + #{textValue, jdbcType=VARCHAR}, + #{alertStatus, jdbcType=VARCHAR}, + #{alertText, jdbcType=VARCHAR}, + #{dataValue, jdbcType=BINARY} + ) + + + diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDtoTest.java deleted file mode 100644 index ef88cb24f84..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDtoTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.measure; - -import com.google.common.base.Strings; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class MeasureDtoTest { - - MeasureDto underTest = new MeasureDto(); - - @Test - void test_getter_and_setter() { - underTest - .setValue(2d) - .setData("text value"); - assertThat(underTest.getValue()).isEqualTo(2d); - assertThat(underTest.getData()).isNotNull(); - } - - @Test - void value_with_text_over_4000_characters() { - assertThat(underTest.setData(Strings.repeat("1", 4001)).getData()).isNotNull(); - } - - @Test - void text_value_under_4000_characters() { - assertThat(underTest.setData("text value").getData()).isEqualTo("text value"); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/PastMeasureDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/PastMeasureDtoTest.java deleted file mode 100644 index 99d153add58..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/PastMeasureDtoTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.measure; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -class PastMeasureDtoTest { - - @Test - void test_getter_and_setter() { - PastMeasureDto dto = new PastMeasureDto() - .setValue(1d) - .setMetricUuid("2"); - - assertThat(dto.hasValue()).isTrue(); - assertThat(dto.getValue()).isEqualTo(1d); - assertThat(dto.getMetricUuid()).isEqualTo("2"); - } - - @Test - void test_has_value() { - PastMeasureDto measureWithValue = new PastMeasureDto() - .setValue(1d) - .setMetricUuid("2"); - assertThat(measureWithValue.hasValue()).isTrue(); - - PastMeasureDto measureWithoutValue = new PastMeasureDto() - .setMetricUuid("2"); - assertThat(measureWithoutValue.hasValue()).isFalse(); - } - - @Test - void get_value_throw_a_NPE_if_value_is_null() { - assertThatThrownBy(() -> new PastMeasureDto().getValue()) - .isInstanceOf(NullPointerException.class); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/ProjectMeasureDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/ProjectMeasureDtoTest.java new file mode 100644 index 00000000000..8c28c8c9d8e --- /dev/null +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/ProjectMeasureDtoTest.java @@ -0,0 +1,49 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.measure; + +import com.google.common.base.Strings; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ProjectMeasureDtoTest { + + ProjectMeasureDto underTest = new ProjectMeasureDto(); + + @Test + void test_getter_and_setter() { + underTest + .setValue(2d) + .setData("text value"); + assertThat(underTest.getValue()).isEqualTo(2d); + assertThat(underTest.getData()).isNotNull(); + } + + @Test + void value_with_text_over_4000_characters() { + assertThat(underTest.setData(Strings.repeat("1", 4001)).getData()).isNotNull(); + } + + @Test + void text_value_under_4000_characters() { + assertThat(underTest.setData("text value").getData()).isEqualTo("text value"); + } +} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/measure/MeasureDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/measure/MeasureDbTester.java index d51698bba4d..1c6cf9abcd3 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/measure/MeasureDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/measure/MeasureDbTester.java @@ -31,7 +31,7 @@ import org.sonar.db.component.SnapshotDto; import org.sonar.db.metric.MetricDto; import static org.sonar.db.measure.MeasureTesting.newLiveMeasure; -import static org.sonar.db.measure.MeasureTesting.newMeasureDto; +import static org.sonar.db.measure.MeasureTesting.newProjectMeasureDto; import static org.sonar.db.metric.MetricTesting.newMetricDto; public class MeasureDbTester { @@ -44,21 +44,21 @@ public class MeasureDbTester { } @SafeVarargs - public final MeasureDto insertMeasure(ComponentDto component, SnapshotDto analysis, MetricDto metricDto, Consumer... consumers) { - MeasureDto measureDto = newMeasureDto(metricDto, component, analysis); - Arrays.stream(consumers).forEach(c -> c.accept(measureDto)); - dbClient.measureDao().insert(dbSession, measureDto); + public final ProjectMeasureDto insertProjectMeasure(ComponentDto component, SnapshotDto analysis, MetricDto metricDto, Consumer... consumers) { + ProjectMeasureDto projectMeasureDto = newProjectMeasureDto(metricDto, component, analysis); + Arrays.stream(consumers).forEach(c -> c.accept(projectMeasureDto)); + dbClient.projectMeasureDao().insert(dbSession, projectMeasureDto); dbSession.commit(); - return measureDto; + return projectMeasureDto; } @SafeVarargs - public final MeasureDto insertMeasure(BranchDto branchDto, SnapshotDto analysis, MetricDto metricDto, Consumer... consumers) { - MeasureDto measureDto = newMeasureDto(metricDto, branchDto.getUuid(), analysis); - Arrays.stream(consumers).forEach(c -> c.accept(measureDto)); - dbClient.measureDao().insert(dbSession, measureDto); + public final ProjectMeasureDto insertProjectMeasure(BranchDto branchDto, SnapshotDto analysis, MetricDto metricDto, Consumer... consumers) { + ProjectMeasureDto projectMeasureDto = MeasureTesting.newProjectMeasureDto(metricDto, branchDto.getUuid(), analysis); + Arrays.stream(consumers).forEach(c -> c.accept(projectMeasureDto)); + dbClient.projectMeasureDao().insert(dbSession, projectMeasureDto); dbSession.commit(); - return measureDto; + return projectMeasureDto; } @SafeVarargs diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/measure/MeasureTesting.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/measure/MeasureTesting.java index 1beb000887c..a01b6d5ba26 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/measure/MeasureTesting.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/measure/MeasureTesting.java @@ -38,23 +38,23 @@ public class MeasureTesting { // static methods only } - public static MeasureDto newMeasureDto(MetricDto metricDto, ComponentDto component, SnapshotDto analysis) { - return newMeasureDto(metricDto, component.uuid(), analysis); + public static ProjectMeasureDto newProjectMeasureDto(MetricDto metricDto, ComponentDto component, SnapshotDto analysis) { + return newProjectMeasureDto(metricDto, component.uuid(), analysis); } - public static MeasureDto newMeasureDto(MetricDto metricDto, String branchUuid, SnapshotDto analysis) { + public static ProjectMeasureDto newProjectMeasureDto(MetricDto metricDto, String branchUuid, SnapshotDto analysis) { checkNotNull(metricDto.getUuid()); checkNotNull(metricDto.getKey()); checkNotNull(branchUuid); checkNotNull(analysis.getUuid()); - return new MeasureDto() + return new ProjectMeasureDto() .setMetricUuid(metricDto.getUuid()) .setComponentUuid(branchUuid) .setAnalysisUuid(analysis.getUuid()); } - public static MeasureDto newMeasure() { - return new MeasureDto() + public static ProjectMeasureDto newProjectMeasure() { + return new ProjectMeasureDto() .setMetricUuid(String.valueOf(cursor++)) .setComponentUuid(String.valueOf(cursor++)) .setAnalysisUuid(String.valueOf(cursor++)) diff --git a/server/sonar-telemetry/src/it/java/org/sonar/telemetry/legacy/TelemetryDataLoaderImplIT.java b/server/sonar-telemetry/src/it/java/org/sonar/telemetry/legacy/TelemetryDataLoaderImplIT.java index fa51a39d5a1..631e8a27197 100644 --- a/server/sonar-telemetry/src/it/java/org/sonar/telemetry/legacy/TelemetryDataLoaderImplIT.java +++ b/server/sonar-telemetry/src/it/java/org/sonar/telemetry/legacy/TelemetryDataLoaderImplIT.java @@ -203,8 +203,8 @@ public class TelemetryDataLoaderImplIT { SnapshotDto project1Analysis = db.components().insertSnapshot(mainBranch1, t -> t.setLast(true).setAnalysisDate(analysisDate)); SnapshotDto project2Analysis = db.components().insertSnapshot(mainBranch2, t -> t.setLast(true).setAnalysisDate(analysisDate)); - db.measures().insertMeasure(mainBranch1, project1Analysis, nclocDistrib, m -> m.setData("java=70;js=30;kotlin=10")); - db.measures().insertMeasure(mainBranch2, project2Analysis, nclocDistrib, m -> m.setData("java=180;js=20")); + db.measures().insertProjectMeasure(mainBranch1, project1Analysis, nclocDistrib, m -> m.setData("java=70;js=30;kotlin=10")); + db.measures().insertProjectMeasure(mainBranch2, project2Analysis, nclocDistrib, m -> m.setData("java=180;js=20")); insertAnalysisProperty(project1Analysis, "prop-uuid-1", SONAR_ANALYSIS_DETECTEDCI, "ci-1"); insertAnalysisProperty(project2Analysis, "prop-uuid-2", SONAR_ANALYSIS_DETECTEDCI, "ci-2"); @@ -347,9 +347,9 @@ public class TelemetryDataLoaderImplIT { SnapshotDto project1Analysis1 = db.components().insertSnapshot(mainBranch1, t -> t.setLast(true).setAnalysisDate(analysisDate)); SnapshotDto project1Analysis2 = db.components().insertSnapshot(mainBranch1, t -> t.setLast(true).setAnalysisDate(analysisDate)); SnapshotDto project2Analysis = db.components().insertSnapshot(mainBranch2, t -> t.setLast(true).setAnalysisDate(analysisDate)); - db.measures().insertMeasure(mainBranch1, project1Analysis1, qg, pm -> pm.setData("OK")); - db.measures().insertMeasure(mainBranch1, project1Analysis2, qg, pm -> pm.setData("ERROR")); - db.measures().insertMeasure(mainBranch2, project2Analysis, qg, pm -> pm.setData("ERROR")); + db.measures().insertProjectMeasure(mainBranch1, project1Analysis1, qg, pm -> pm.setData("OK")); + db.measures().insertProjectMeasure(mainBranch1, project1Analysis2, qg, pm -> pm.setData("ERROR")); + db.measures().insertProjectMeasure(mainBranch2, project2Analysis, qg, pm -> pm.setData("ERROR")); var branch1 = db.components().insertProjectBranch(mainBranch1, branchDto -> branchDto.setKey("reference")); var branch2 = db.components().insertProjectBranch(mainBranch1, branchDto -> branchDto.setKey("custom")); @@ -424,8 +424,8 @@ public class TelemetryDataLoaderImplIT { SnapshotDto project1Analysis = db.components().insertSnapshot(mainBranch, t -> t.setLast(true)); SnapshotDto project2Analysis = db.components().insertSnapshot(branch, t -> t.setLast(true)); - db.measures().insertMeasure(mainBranch, project1Analysis, nclocDistrib, m -> m.setData("java=70;js=30;kotlin=10")); - db.measures().insertMeasure(branch, project2Analysis, nclocDistrib, m -> m.setData("java=100;js=50;kotlin=30")); + db.measures().insertProjectMeasure(mainBranch, project1Analysis, nclocDistrib, m -> m.setData("java=70;js=30;kotlin=10")); + db.measures().insertProjectMeasure(branch, project2Analysis, nclocDistrib, m -> m.setData("java=100;js=50;kotlin=30")); TelemetryData data = communityUnderTest.load(); @@ -467,8 +467,8 @@ public class TelemetryDataLoaderImplIT { SnapshotDto project1Analysis = db.components().insertSnapshot(mainBranch, t -> t.setLast(true)); SnapshotDto project2Analysis = db.components().insertSnapshot(branch, t -> t.setLast(true)); - db.measures().insertMeasure(mainBranch, project1Analysis, nclocDistrib, m -> m.setData("java=70;js=30;kotlin=10")); - db.measures().insertMeasure(branch, project2Analysis, nclocDistrib, m -> m.setData("java=100;js=50;kotlin=30")); + db.measures().insertProjectMeasure(mainBranch, project1Analysis, nclocDistrib, m -> m.setData("java=70;js=30;kotlin=10")); + db.measures().insertProjectMeasure(branch, project2Analysis, nclocDistrib, m -> m.setData("java=100;js=50;kotlin=30")); TelemetryData data = communityUnderTest.load(); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java index c29e60eb89c..1a153ec3c93 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java @@ -35,7 +35,7 @@ import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ProjectData; import org.sonar.db.component.SnapshotDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.metric.MetricDto; import org.sonar.server.component.TestComponentFinder; import org.sonar.server.exceptions.ForbiddenException; @@ -62,7 +62,7 @@ import static org.sonar.db.component.BranchType.PULL_REQUEST; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.SnapshotDto.STATUS_UNPROCESSED; import static org.sonar.db.component.SnapshotTesting.newAnalysis; -import static org.sonar.db.measure.MeasureTesting.newMeasureDto; +import static org.sonar.db.measure.MeasureTesting.newProjectMeasureDto; import static org.sonar.db.metric.MetricTesting.newMetricDto; import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_BRANCH; import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_COMPONENT; @@ -146,8 +146,8 @@ public class SearchHistoryActionIT { @Test public void return_metrics() { - dbClient.measureDao().insert(dbSession, newMeasureDto(complexityMetric, project.mainBranchUuid(), analysis).setValue(42.0d)); - dbClient.measureDao().insert(dbSession, newMeasureDto(acceptedIssuesMetric, project.mainBranchUuid(), analysis).setValue(10.0d)); + dbClient.projectMeasureDao().insert(dbSession, newProjectMeasureDto(complexityMetric, project.mainBranchUuid(), analysis).setValue(42.0d)); + dbClient.projectMeasureDao().insert(dbSession, newProjectMeasureDto(acceptedIssuesMetric, project.mainBranchUuid(), analysis).setValue(10.0d)); db.commit(); SearchHistoryRequest request = SearchHistoryRequest.builder() @@ -164,7 +164,7 @@ public class SearchHistoryActionIT { @Test public void return_renamed_and_deprecated_metric() { - dbClient.measureDao().insert(dbSession, newMeasureDto(acceptedIssuesMetric, project.mainBranchUuid(), analysis).setValue(10.0d)); + dbClient.projectMeasureDao().insert(dbSession, newProjectMeasureDto(acceptedIssuesMetric, project.mainBranchUuid(), analysis).setValue(10.0d)); db.commit(); SearchHistoryRequest request = SearchHistoryRequest.builder() @@ -183,13 +183,13 @@ public class SearchHistoryActionIT { public void return_measures() { SnapshotDto laterAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(project.getMainBranchDto()).setCreatedAt(analysis.getCreatedAt() + 42_000)); ComponentDto file = db.components().insertComponent(newFileDto(project.getMainBranchComponent())); - dbClient.measureDao().insert(dbSession, - newMeasureDto(complexityMetric, project.mainBranchUuid(), analysis).setValue(101d), - newMeasureDto(complexityMetric, project.mainBranchUuid(), laterAnalysis).setValue(100d), - newMeasureDto(complexityMetric, file, analysis).setValue(42d), - newMeasureDto(nclocMetric, project.mainBranchUuid(), analysis).setValue(201d), - newMeasureDto(newViolationMetric, project.mainBranchUuid(), analysis).setValue(5d), - newMeasureDto(newViolationMetric, project.mainBranchUuid(), laterAnalysis).setValue(10d)); + dbClient.projectMeasureDao().insert(dbSession, + newProjectMeasureDto(complexityMetric, project.mainBranchUuid(), analysis).setValue(101d), + newProjectMeasureDto(complexityMetric, project.mainBranchUuid(), laterAnalysis).setValue(100d), + newProjectMeasureDto(complexityMetric, file, analysis).setValue(42d), + newProjectMeasureDto(nclocMetric, project.mainBranchUuid(), analysis).setValue(201d), + newProjectMeasureDto(newViolationMetric, project.mainBranchUuid(), analysis).setValue(5d), + newProjectMeasureDto(newViolationMetric, project.mainBranchUuid(), laterAnalysis).setValue(10d)); db.commit(); SearchHistoryRequest request = SearchHistoryRequest.builder() @@ -228,7 +228,7 @@ public class SearchHistoryActionIT { .registerBranches(project.getMainBranchDto()); List analysisDates = LongStream.rangeClosed(1, 9) .mapToObj(i -> dbClient.snapshotDao().insert(dbSession, newAnalysis(project.mainBranchUuid()).setCreatedAt(i * 1_000_000_000))) - .peek(a -> dbClient.measureDao().insert(dbSession, newMeasureDto(complexityMetric, project.mainBranchUuid(), a).setValue(101d))) + .peek(a -> dbClient.projectMeasureDao().insert(dbSession, newProjectMeasureDto(complexityMetric, project.mainBranchUuid(), a).setValue(101d))) .map(a -> formatDateTime(a.getCreatedAt())) .toList(); db.commit(); @@ -253,7 +253,7 @@ public class SearchHistoryActionIT { .registerBranches(project.getMainBranchDto()); List analysisDates = LongStream.rangeClosed(1, 9) .mapToObj(i -> dbClient.snapshotDao().insert(dbSession, newAnalysis(project.mainBranchUuid()).setCreatedAt(System2.INSTANCE.now() + i * 1_000_000_000L))) - .peek(a -> dbClient.measureDao().insert(dbSession, newMeasureDto(complexityMetric, project.mainBranchUuid(), a).setValue(Double.valueOf(a.getCreatedAt())))) + .peek(a -> dbClient.projectMeasureDao().insert(dbSession, newProjectMeasureDto(complexityMetric, project.mainBranchUuid(), a).setValue(Double.valueOf(a.getCreatedAt())))) .map(a -> formatDateTime(a.getCreatedAt())) .toList(); db.commit(); @@ -322,7 +322,7 @@ public class SearchHistoryActionIT { userSession.addProjectBranchMapping(project.projectUuid(), branch); ComponentDto file = db.components().insertComponent(newFileDto(branch, project.mainBranchUuid())); SnapshotDto analysis = db.components().insertSnapshot(branch); - MeasureDto measure = db.measures().insertMeasure(file, analysis, nclocMetric, m -> m.setValue(2d)); + ProjectMeasureDto measure = db.measures().insertProjectMeasure(file, analysis, nclocMetric, m -> m.setValue(2d)); SearchHistoryResponse result = ws.newRequest() .setParam(PARAM_COMPONENT, file.getKey()) @@ -346,7 +346,7 @@ public class SearchHistoryActionIT { userSession.addProjectBranchMapping(project.projectUuid(), branch); ComponentDto file = db.components().insertComponent(newFileDto(branch, project.mainBranchUuid())); SnapshotDto analysis = db.components().insertSnapshot(branch); - MeasureDto measure = db.measures().insertMeasure(file, analysis, nclocMetric, m -> m.setValue(2d)); + ProjectMeasureDto measure = db.measures().insertProjectMeasure(file, analysis, nclocMetric, m -> m.setValue(2d)); SearchHistoryResponse result = ws.newRequest() .setParam(PARAM_COMPONENT, file.getKey()) @@ -474,10 +474,10 @@ public class SearchHistoryActionIT { long now = parseDateTime("2017-01-23T17:00:53+0100").getTime(); LongStream.rangeClosed(0, 2) .mapToObj(i -> dbClient.snapshotDao().insert(dbSession, newAnalysis(project.getMainBranchDto()).setCreatedAt(now + i * 24 * 1_000 * 60 * 60))) - .forEach(analysis -> dbClient.measureDao().insert(dbSession, - newMeasureDto(complexityMetric, project.mainBranchUuid(), analysis).setValue(45d), - newMeasureDto(newViolationMetric, project.mainBranchUuid(), analysis).setValue(46d), - newMeasureDto(nclocMetric, project.mainBranchUuid(), analysis).setValue(47d))); + .forEach(locAnalysis -> dbClient.projectMeasureDao().insert(dbSession, + newProjectMeasureDto(complexityMetric, project.mainBranchUuid(), locAnalysis).setValue(45d), + newProjectMeasureDto(newViolationMetric, project.mainBranchUuid(), locAnalysis).setValue(46d), + newProjectMeasureDto(nclocMetric, project.mainBranchUuid(), locAnalysis).setValue(47d))); db.commit(); String result = ws.newRequest() @@ -490,7 +490,7 @@ public class SearchHistoryActionIT { @Test public void measure_without_values() { - dbClient.measureDao().insert(dbSession, newMeasureDto(stringMetric, project.mainBranchUuid(), analysis).setValue(null).setData(null)); + dbClient.projectMeasureDao().insert(dbSession, newProjectMeasureDto(stringMetric, project.mainBranchUuid(), analysis).setValue(null).setData(null)); db.commit(); SearchHistoryRequest request = SearchHistoryRequest.builder() diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/ProjectStatusActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/ProjectStatusActionIT.java index bad2353ba3f..10e2027da73 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/ProjectStatusActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/ProjectStatusActionIT.java @@ -61,7 +61,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.db.component.SnapshotTesting.newAnalysis; import static org.sonar.db.measure.MeasureTesting.newLiveMeasure; -import static org.sonar.db.measure.MeasureTesting.newMeasureDto; +import static org.sonar.db.measure.MeasureTesting.newProjectMeasureDto; import static org.sonar.db.metric.MetricTesting.newMetricDto; import static org.sonar.server.qualitygate.QualityGateCaycStatus.COMPLIANT; import static org.sonar.server.qualitygate.QualityGateCaycStatus.NON_COMPLIANT; @@ -115,8 +115,8 @@ public class ProjectStatusActionIT { .setPeriodMode("last_version") .setPeriodParam("2015-12-07") .setPeriodDate(956789123987L)); - dbClient.measureDao().insert(dbSession, - newMeasureDto(gateDetailsMetric, mainBranch, snapshot) + dbClient.projectMeasureDao().insert(dbSession, + newProjectMeasureDto(gateDetailsMetric, mainBranch, snapshot) .setData(IOUtils.toString(getClass().getResource("ProjectStatusActionIT/measure_data.json"), StandardCharsets.UTF_8))); dbSession.commit(); @@ -142,11 +142,11 @@ public class ProjectStatusActionIT { .setPeriodParam("2016-12-07") .setPeriodDate(1_500L)); MetricDto gateDetailsMetric = insertGateDetailMetric(); - dbClient.measureDao().insert(dbSession, - newMeasureDto(gateDetailsMetric, mainBranch, pastAnalysis) + dbClient.projectMeasureDao().insert(dbSession, + newProjectMeasureDto(gateDetailsMetric, mainBranch, pastAnalysis) .setData(IOUtils.toString(getClass().getResource("ProjectStatusActionIT/measure_data.json")))); - dbClient.measureDao().insert(dbSession, - newMeasureDto(gateDetailsMetric, mainBranch, lastAnalysis) + dbClient.projectMeasureDao().insert(dbSession, + newProjectMeasureDto(gateDetailsMetric, mainBranch, lastAnalysis) .setData("not_used")); dbSession.commit(); userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); @@ -196,11 +196,11 @@ public class ProjectStatusActionIT { .setPeriodParam("2016-12-07") .setPeriodDate(1_500L)); MetricDto gateDetailsMetric = insertGateDetailMetric(); - dbClient.measureDao().insert(dbSession, - newMeasureDto(gateDetailsMetric, branch, pastAnalysis) + dbClient.projectMeasureDao().insert(dbSession, + newProjectMeasureDto(gateDetailsMetric, branch, pastAnalysis) .setData(IOUtils.toString(getClass().getResource("ProjectStatusActionIT/measure_data.json")))); - dbClient.measureDao().insert(dbSession, - newMeasureDto(gateDetailsMetric, branch, lastAnalysis) + dbClient.projectMeasureDao().insert(dbSession, + newProjectMeasureDto(gateDetailsMetric, branch, lastAnalysis) .setData("not_used")); dbSession.commit(); userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasureDtoToWsMeasure.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasureDtoToWsMeasure.java index 87e20c51bcd..4651174acb9 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasureDtoToWsMeasure.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasureDtoToWsMeasure.java @@ -21,7 +21,7 @@ package org.sonar.server.measure.ws; import javax.annotation.Nullable; import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.metric.MetricDto; import org.sonarqube.ws.Measures; import org.sonarqube.ws.Measures.Measure; @@ -36,10 +36,10 @@ class MeasureDtoToWsMeasure { // static methods } - static void updateMeasureBuilder(Measure.Builder measureBuilder, MetricDto metricDto, MeasureDto measureDto) { - double value = measureDto.getValue() == null ? Double.NaN : measureDto.getValue(); + static void updateMeasureBuilder(Measure.Builder measureBuilder, MetricDto metricDto, ProjectMeasureDto projectMeasureDto) { + double value = projectMeasureDto.getValue() == null ? Double.NaN : projectMeasureDto.getValue(); boolean onNewCode = metricDto.getKey().startsWith("new_"); - updateMeasureBuilder(measureBuilder, metricDto, value, measureDto.getData(), onNewCode); + updateMeasureBuilder(measureBuilder, metricDto, value, projectMeasureDto.getData(), onNewCode); } static void updateMeasureBuilder(Measure.Builder measureBuilder, MetricDto metricDto, LiveMeasureDto measureDto) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasureValueFormatter.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasureValueFormatter.java index 1c40cf82fad..c9c2bd42db4 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasureValueFormatter.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasureValueFormatter.java @@ -23,7 +23,7 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.measures.Metric; import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.metric.MetricDto; public class MeasureValueFormatter { @@ -41,7 +41,7 @@ public class MeasureValueFormatter { } @CheckForNull - static String formatMeasureValue(MeasureDto measure, MetricDto metric) { + static String formatMeasureValue(ProjectMeasureDto measure, MetricDto metric) { Double doubleValue = measure.getValue(); String stringValue = measure.getData(); return formatMeasureValue(doubleValue == null ? Double.NaN : doubleValue, stringValue, metric); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java index d8822093948..578432f2784 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java @@ -44,7 +44,7 @@ import org.sonar.db.component.SnapshotDto; import org.sonar.db.component.SnapshotQuery; import org.sonar.db.component.SnapshotQuery.SORT_FIELD; import org.sonar.db.component.SnapshotQuery.SORT_ORDER; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.measure.PastMeasureQuery; import org.sonar.db.metric.MetricDto; import org.sonar.db.metric.RemovedMetricConverter; @@ -196,7 +196,7 @@ public class SearchHistoryAction implements MeasuresWsAction { return component; } - private List searchMeasures(DbSession dbSession, SearchHistoryRequest request, SearchHistoryResult result) { + private List searchMeasures(DbSession dbSession, SearchHistoryRequest request, SearchHistoryResult result) { Date from = parseStartingDateOrDateTime(request.getFrom()); Date to = parseEndingDateOrDateTime(request.getTo()); PastMeasureQuery dbQuery = new PastMeasureQuery( @@ -204,7 +204,7 @@ public class SearchHistoryAction implements MeasuresWsAction { result.getMetrics().stream().map(MetricDto::getUuid).toList(), from == null ? null : from.getTime(), to == null ? null : (to.getTime() + 1_000L)); - return dbClient.measureDao().selectPastMeasures(dbSession, dbQuery); + return dbClient.projectMeasureDao().selectPastMeasures(dbSession, dbQuery); } private List searchAnalyses(DbSession dbSession, SearchHistoryRequest request, ComponentDto component) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResponseFactory.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResponseFactory.java index 7d3a8d06bf9..1164b1670da 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResponseFactory.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResponseFactory.java @@ -28,7 +28,7 @@ import java.util.function.UnaryOperator; import java.util.stream.Collectors; import javax.annotation.Nullable; import org.sonar.db.component.SnapshotDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.metric.MetricDto; import org.sonarqube.ws.Measures.SearchHistoryResponse; import org.sonarqube.ws.Measures.SearchHistoryResponse.HistoryMeasure; @@ -64,7 +64,7 @@ class SearchHistoryResponseFactory { private UnaryOperator addMeasures() { Map metricsByUuid = result.getMetrics().stream().collect(Collectors.toMap(MetricDto::getUuid, Function.identity())); Map analysesByUuid = result.getAnalyses().stream().collect(Collectors.toMap(SnapshotDto::getUuid, Function.identity())); - Table measuresByMetricByAnalysis = HashBasedTable.create(result.getMetrics().size(), result.getAnalyses().size()); + Table measuresByMetricByAnalysis = HashBasedTable.create(result.getMetrics().size(), result.getAnalyses().size()); result.getMeasures().forEach(m -> measuresByMetricByAnalysis.put(metricsByUuid.get(m.getMetricUuid()), analysesByUuid.get(m.getAnalysisUuid()), m)); return response -> { @@ -79,7 +79,7 @@ class SearchHistoryResponseFactory { }; } - private UnaryOperator addValues(Map measuresByAnalysis) { + private UnaryOperator addValues(Map measuresByAnalysis) { return metric -> { result.getAnalyses().stream() .map(clearValue()) @@ -98,7 +98,7 @@ class SearchHistoryResponseFactory { }; } - private SnapshotDto addValue(SnapshotDto analysis, MetricDto dbMetric, @Nullable MeasureDto dbMeasure) { + private SnapshotDto addValue(SnapshotDto analysis, MetricDto dbMetric, @Nullable ProjectMeasureDto dbMeasure) { if (dbMeasure != null) { String measureValue = formatMeasureValue(dbMeasure, dbMetric); if (measureValue != null) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java index b5f193dc4d8..2d7aea1f778 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java @@ -28,7 +28,7 @@ import java.util.Set; import java.util.stream.Collectors; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.metric.MetricDto; import org.sonarqube.ws.Common; @@ -43,7 +43,7 @@ public class SearchHistoryResult { private final int pageSize; private List analyses; private List metrics; - private List measures; + private List measures; private Common.Paging paging; private ComponentDto component; private List requestedMetrics; @@ -83,14 +83,14 @@ public class SearchHistoryResult { return this; } - public List getMeasures() { + public List getMeasures() { return requireNonNull(measures); } - public SearchHistoryResult setMeasures(List measures) { + public SearchHistoryResult setMeasures(List measures) { Set analysisUuids = analyses.stream().map(SnapshotDto::getUuid).collect(Collectors.toSet()); - ImmutableList.Builder measuresBuilder = ImmutableList.builder(); - List filteredMeasures = measures.stream() + ImmutableList.Builder measuresBuilder = ImmutableList.builder(); + List filteredMeasures = measures.stream() .filter(measure -> analysisUuids.contains(measure.getAnalysisUuid())) .toList(); measuresBuilder.addAll(filteredMeasures); @@ -108,7 +108,7 @@ public class SearchHistoryResult { *
  • metric is optimized for best value
  • * */ - private List computeBestValues(List measures) { + private List computeBestValues(List measures) { if (!isEligibleForBestValue().test(component)) { return emptyList(); } @@ -116,9 +116,9 @@ public class SearchHistoryResult { requireNonNull(metrics); requireNonNull(analyses); - Table measuresByMetricUuidAndAnalysisUuid = HashBasedTable.create(metrics.size(), analyses.size()); + Table measuresByMetricUuidAndAnalysisUuid = HashBasedTable.create(metrics.size(), analyses.size()); measures.forEach(measure -> measuresByMetricUuidAndAnalysisUuid.put(measure.getMetricUuid(), measure.getAnalysisUuid(), measure)); - List bestValues = new ArrayList<>(); + List bestValues = new ArrayList<>(); metrics.stream() .filter(isOptimizedForBestValue()) .forEach(metric -> analyses.stream() @@ -129,8 +129,8 @@ public class SearchHistoryResult { return bestValues; } - private static MeasureDto toBestValue(MetricDto metric, SnapshotDto analysis) { - return new MeasureDto() + private static ProjectMeasureDto toBestValue(MetricDto metric, SnapshotDto analysis) { + return new ProjectMeasureDto() .setMetricUuid(metric.getUuid()) .setAnalysisUuid(analysis.getUuid()) .setValue(metric.getBestValue()); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java index 4cde2c5129f..9c034901fbf 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java @@ -36,7 +36,7 @@ import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; import org.sonar.db.component.SnapshotDto; import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.project.ProjectDto; import org.sonar.server.component.ComponentFinder; @@ -211,8 +211,8 @@ public class ProjectStatusAction implements QualityGatesWsAction { } // get the gate status as it was computed during the specified analysis String analysisUuid = projectAndSnapshot.snapshotDto.get().getUuid(); - return dbClient.measureDao().selectMeasure(dbSession, analysisUuid, projectAndSnapshot.branch.getUuid(), CoreMetrics.QUALITY_GATE_DETAILS_KEY) - .map(MeasureDto::getData); + return dbClient.projectMeasureDao().selectMeasure(dbSession, analysisUuid, projectAndSnapshot.branch.getUuid(), CoreMetrics.QUALITY_GATE_DETAILS_KEY) + .map(ProjectMeasureDto::getData); } // do not restrict to a specified analysis, use the live measure diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/MeasureValueFormatterTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/MeasureValueFormatterTest.java index 06841360527..e06d569d5b6 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/MeasureValueFormatterTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/MeasureValueFormatterTest.java @@ -21,7 +21,7 @@ package org.sonar.server.measure.ws; import org.junit.Test; import org.sonar.api.measures.Metric; -import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.ProjectMeasureDto; import org.sonar.db.metric.MetricDto; import static org.assertj.core.api.Assertions.assertThat; @@ -71,11 +71,11 @@ public class MeasureValueFormatterTest { return newMetricDto().setValueType(valueType.name()); } - private static MeasureDto newNumericMeasure(Double value) { - return new MeasureDto().setValue(value); + private static ProjectMeasureDto newNumericMeasure(Double value) { + return new ProjectMeasureDto().setValue(value); } - private static MeasureDto newTextMeasure(String data) { - return new MeasureDto().setData(data); + private static ProjectMeasureDto newTextMeasure(String data) { + return new ProjectMeasureDto().setData(data); } }