From af2fe3233a3ec0cc5a3f6ca52eb2a9c359436bff Mon Sep 17 00:00:00 2001 From: Viktor Vorona Date: Fri, 15 Nov 2024 09:57:18 +0100 Subject: [PATCH] SONAR-23592 Do not use best value in component_tree if measure is not computed --- .../measure/ws/ComponentTreeActionIT.java | 65 +++++++++++++++---- .../measure/ws/ComponentTreeAction.java | 6 +- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java index 3e4dba53513..007dd505f68 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java @@ -80,6 +80,7 @@ import static org.sonar.api.utils.DateUtils.parseDateTime; import static org.sonar.api.web.UserRole.USER; import static org.sonar.db.component.BranchType.PULL_REQUEST; import static org.sonar.db.component.ComponentDbTester.toProjectDto; +import static org.sonar.db.component.ComponentTesting.newBranchDto; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newProjectCopy; @@ -238,7 +239,7 @@ class ComponentTreeActionIT { @Test void load_measures_and_periods() { ComponentDto mainBranch = db.components().insertPrivateProject().getMainBranchComponent(); - SnapshotDto projectSnapshot = dbClient.snapshotDao().insert(dbSession, + dbClient.snapshotDao().insert(dbSession, newAnalysis(mainBranch) .setPeriodDate(System.currentTimeMillis()) .setPeriodMode("last_version") @@ -270,22 +271,22 @@ class ComponentTreeActionIT { } @Test - void load_measures_with_best_value() { + void load_whenMeasuresWithoutValuesButComputed_shouldBeReplacedWithBestValues() { ComponentDto mainBranch = db.components().insertPrivateProject().getMainBranchComponent(); - SnapshotDto projectSnapshot = db.components().insertSnapshot(mainBranch); + db.components().insertSnapshot(mainBranch); userSession.anonymous().addProjectPermission(USER, mainBranch); ComponentDto directory = newDirectory(mainBranch, "directory-uuid", "path/to/directory").setName("directory-1"); db.components().insertComponent(directory); ComponentDto file = newFileDto(directory, null, "file-uuid").setName("file-1"); db.components().insertComponent(file); MetricDto coverage = insertCoverageMetric(); - dbClient.metricDao().insert(dbSession, MetricTesting.newMetricDto() + MetricDto ncloc = dbClient.metricDao().insert(dbSession, MetricTesting.newMetricDto() .setKey("ncloc") .setValueType(INT.name()) .setOptimizedBestValue(true) .setBestValue(100d) .setWorstValue(1000d)); - dbClient.metricDao().insert(dbSession, newMetricDto() + MetricDto newViolations = dbClient.metricDao().insert(dbSession, newMetricDto() .setKey("new_violations") .setOptimizedBestValue(true) .setBestValue(1984.0d) @@ -293,6 +294,8 @@ class ComponentTreeActionIT { db.commit(); db.measures().insertMeasure(file, m -> m.addValue(coverage.getKey(), 15.5d)); db.measures().insertMeasure(directory, m -> m.addValue(coverage.getKey(), 42.0d)); + db.measures().insertMeasure(mainBranch, m -> m.addValue(ncloc.getKey(), 50d)); + db.measures().insertMeasure(mainBranch, m -> m.addValue(newViolations.getKey(), 0d)); ComponentTreeWsResponse response = ws.newRequest() .setParam(PARAM_COMPONENT, mainBranch.getKey()) @@ -316,7 +319,44 @@ class ComponentTreeActionIT { } @Test - void return_is_best_value_on_leak_measures() { + void load_whenMeasuresWithoutValuesAndNotComputed_shouldNotBeReplacedWithBestValues() { + ComponentDto mainBranch = db.components().insertPrivateProject().getMainBranchComponent(); + db.components().insertSnapshot(mainBranch); + userSession.anonymous().addProjectPermission(USER, mainBranch); + ComponentDto file = newFileDto(mainBranch, null, "file-uuid").setName("file-1"); + db.components().insertComponent(file); + MetricDto coverage = insertCoverageMetric(); + MetricDto ncloc = dbClient.metricDao().insert(dbSession, MetricTesting.newMetricDto() + .setKey("ncloc") + .setValueType(INT.name()) + .setOptimizedBestValue(true) + .setBestValue(100d) + .setWorstValue(1000d)); + dbClient.metricDao().insert(dbSession, newMetricDto() + .setKey("violations") + .setOptimizedBestValue(true) + .setBestValue(1984.0d) + .setValueType(INT.name())); + db.commit(); + db.measures().insertMeasure(file, m -> m.addValue(coverage.getKey(), 15.5d)); + db.measures().insertMeasure(mainBranch, m -> m.addValue(ncloc.getKey(), 50d)); + + ComponentTreeWsResponse response = ws.newRequest() + .setParam(PARAM_COMPONENT, mainBranch.getKey()) + .setParam(PARAM_METRIC_KEYS, "ncloc,coverage,violations") + .setParam(PARAM_ADDITIONAL_FIELDS, "metrics") + .executeProtobuf(ComponentTreeWsResponse.class); + + // file measures + List fileMeasures = response.getComponentsList().get(0).getMeasuresList(); + assertThat(fileMeasures) + .extracting(Measure::getMetric, Measure::getValue, Measure::getBestValue, Measure::hasBestValue) + .containsExactlyInAnyOrder(tuple("ncloc", "100", true, true), + tuple("coverage", "15.5", false, false)); + } + + @Test + void load_whenLeakMeasuresAreRequested_shouldBeReplacedWithBestValues() { ComponentDto mainBranch = db.components().insertPrivateProject().getMainBranchComponent(); db.components().insertSnapshot(mainBranch); userSession.anonymous().addProjectPermission(USER, mainBranch); @@ -361,7 +401,7 @@ class ComponentTreeActionIT { void use_best_value_for_rating() { ComponentDto mainBranch = db.components().insertPrivateProject().getMainBranchComponent(); userSession.anonymous().addProjectPermission(USER, mainBranch); - SnapshotDto projectSnapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(mainBranch) + dbClient.snapshotDao().insert(dbSession, newAnalysis(mainBranch) .setPeriodDate(parseDateTime("2016-01-11T10:49:50+0100").getTime()) .setPeriodMode("previous_version") .setPeriodParam("1.0-SNAPSHOT")); @@ -376,6 +416,7 @@ class ComponentTreeActionIT { .setValueType(RATING.name())); db.commit(); db.measures().insertMeasure(directory, m -> m.addValue(metric.getKey(), 2d)); + db.measures().insertMeasure(mainBranch, m -> m.addValue(metric.getKey(), 3d)); ComponentTreeWsResponse response = ws.newRequest() .setParam(PARAM_COMPONENT, mainBranch.getKey()) @@ -396,7 +437,7 @@ class ComponentTreeActionIT { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); addProjectPermission(projectData); - SnapshotDto projectSnapshot = db.components().insertSnapshot(mainBranch); + db.components().insertSnapshot(mainBranch); ComponentDto file9 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-9").setName("file-1").setKey("file-9-key" )); ComponentDto file8 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-8").setName("file-1").setKey("file-8-key" @@ -449,7 +490,7 @@ class ComponentTreeActionIT { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); addProjectPermission(projectData); - SnapshotDto projectSnapshot = db.components().insertSnapshot(mainBranch); + db.components().insertSnapshot(mainBranch); ComponentDto file4 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-4").setKey("file-4-key")); ComponentDto file3 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-3").setKey("file-3-key")); ComponentDto file1 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-1").setKey("file-1-key")); @@ -477,7 +518,7 @@ class ComponentTreeActionIT { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); addProjectPermission(projectData); - SnapshotDto projectSnapshot = db.components().insertSnapshot(mainBranch); + db.components().insertSnapshot(mainBranch); ComponentDto file1 = newFileDto(mainBranch, null, "file-uuid-1").setKey("file-1-key"); ComponentDto file2 = newFileDto(mainBranch, null, "file-uuid-2").setKey("file-2-key"); ComponentDto file3 = newFileDto(mainBranch, null, "file-uuid-3").setKey("file-3-key"); @@ -512,7 +553,7 @@ class ComponentTreeActionIT { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); addProjectPermission(projectData); - SnapshotDto projectSnapshot = db.components().insertSnapshot(mainBranch); + db.components().insertSnapshot(mainBranch); ComponentDto file3 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-3").setKey("file-3-key")); ComponentDto file1 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-1").setKey("file-1-key")); ComponentDto file2 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-2").setKey("file-2-key")); @@ -539,7 +580,7 @@ class ComponentTreeActionIT { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); addProjectPermission(projectData); - SnapshotDto projectSnapshot = db.components().insertSnapshot(mainBranch); + db.components().insertSnapshot(mainBranch); ComponentDto file4 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-4").setKey("file-4-key")); ComponentDto file3 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-3").setKey("file-3-key")); ComponentDto file2 = db.components().insertComponent(newFileDto(mainBranch, null, "file-uuid-2").setKey("file-2-key")); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java index d6d8bc8fc91..696fed27ea0 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java @@ -588,7 +588,9 @@ public class ComponentTreeAction implements MeasuresWsAction { }); }); - addBestValuesToMeasures(measuresByComponentUuidAndMetric, components, metrics); + Set baseComponentMetricDtos = measuresByComponentUuidAndMetric.row(baseComponent.uuid()).keySet(); + + addBestValuesToMeasures(measuresByComponentUuidAndMetric, components, baseComponentMetricDtos, metrics); return measuresByComponentUuidAndMetric; } @@ -602,8 +604,10 @@ public class ComponentTreeAction implements MeasuresWsAction { */ private static void addBestValuesToMeasures(Table measuresByComponentUuidAndMetric, List components, + Set baseComponentMetricDtos, List metrics) { List metricDtosWithBestValueMeasure = metrics.stream() + .filter(baseComponentMetricDtos::contains) .filter(MetricDtoFunctions.isOptimizedForBestValue()) .map(new MetricDtoToMetricDtoWithBestValue()) .toList(); -- 2.39.5