]> source.dussan.org Git - sonarqube.git/blob
6eba63a30966d24d78c8623641d4ab12c4bbd91b
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.server.platform.db.migration.version.v108;
21
22 import java.sql.SQLException;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.stream.Collectors;
26 import org.junit.jupiter.api.BeforeEach;
27 import org.junit.jupiter.api.Test;
28 import org.junit.jupiter.api.extension.RegisterExtension;
29 import org.sonar.core.util.UuidFactoryImpl;
30 import org.sonar.db.MigrationDbTester;
31
32 import static org.assertj.core.api.Assertions.assertThat;
33 import static org.sonar.api.measures.CoreMetrics.MAINTAINABILITY_ISSUES_KEY;
34 import static org.sonar.api.measures.CoreMetrics.NEW_MAINTAINABILITY_ISSUES_KEY;
35 import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_ISSUES_KEY;
36 import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_ISSUES_KEY;
37 import static org.sonar.api.measures.CoreMetrics.RELIABILITY_ISSUES_KEY;
38 import static org.sonar.api.measures.CoreMetrics.SECURITY_ISSUES_KEY;
39 import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY;
40 import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY;
41 import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_ISSUES_KEY;
42 import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY;
43 import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY;
44 import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_ISSUES_KEY;
45 import static org.sonar.server.platform.db.migration.version.v108.MeasureMigration.MIGRATION_MAP;
46
47 class MigrateProjectMeasuresDeprecatedMetricsTest {
48   private static final String ANALYSIS_UUID_1 = UuidFactoryImpl.INSTANCE.create();
49   private static final String ANALYSIS_UUID_2 = UuidFactoryImpl.INSTANCE.create();
50   @RegisterExtension
51   private final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MigrateProjectMeasuresDeprecatedMetrics.class);
52   private final MigrateProjectMeasuresDeprecatedMetrics underTest = new MigrateProjectMeasuresDeprecatedMetrics(db.database(),
53     UuidFactoryImpl.INSTANCE);
54   private Map<String, String> metricsToMigrate;
55   private Map<String, String> replacementMetrics;
56
57   @BeforeEach
58   void init() {
59     metricsToMigrate = insertMetricsToMigrate();
60     replacementMetrics = insertReplacementMetrics();
61   }
62
63   @Test
64   void execute_shouldCreateNewMetrics() throws SQLException {
65     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1");
66     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "3");
67     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "5");
68     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "11");
69     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "13");
70     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "15");
71     underTest.execute();
72
73     assertThat(db.select("select metric_uuid, value from project_measures where metric_uuid in (%s)"
74       .formatted(replacementMetrics.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(",")))))
75       .hasSize(6)
76       .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 1.0)))
77       .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY), "value", 3.0)))
78       .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 5.0)))
79       .contains((Map.of("metric_uuid", replacementMetrics.get(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 11.0)))
80       .contains((Map.of("metric_uuid", replacementMetrics.get(NEW_SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY), "value", 13.0)))
81       .contains((Map.of("metric_uuid", replacementMetrics.get(NEW_SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 15.0)));
82   }
83
84   @Test
85   void execute_shouldBeReentrant() throws SQLException {
86     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1");
87     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "3");
88     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "5");
89     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "11");
90     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "13");
91     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "15");
92     underTest.execute();
93     underTest.execute();
94     assertThat(db.select("select * from project_measures"))
95       .hasSize(MIGRATION_MAP.size() * 2);
96   }
97
98   @Test
99   void execute_whenValueCannotBeConverted_shouldCreateOtherNewMetrics() throws SQLException {
100     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1");
101     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "NOT_VALID_NUMBER");
102     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "5");
103     underTest.execute();
104
105     assertThat(db.select("select metric_uuid, value from project_measures where metric_uuid in (%s)"
106       .formatted(replacementMetrics.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(",")))))
107       .hasSize(2)
108       .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 1.0)))
109       .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 5.0)));
110   }
111
112   @Test
113   void execute_whenWasPartiallyMigrated_shouldContinueWithOtherAnalysis() throws SQLException {
114
115     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1");
116     createProjectMeasureForNewMetric(replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, 1);
117
118     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_2, "4");
119     createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_2, "5");
120     underTest.execute();
121
122     assertThat(db.select("select metric_uuid, value, analysis_uuid from project_measures where metric_uuid in (%s)"
123       .formatted(replacementMetrics.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(",")))))
124       .hasSize(3)
125       .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 1.0, "analysis_uuid"
126         , ANALYSIS_UUID_1)))
127       .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 4.0, "analysis_uuid"
128         , ANALYSIS_UUID_2)))
129       .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 5.0, "analysis_uuid",
130         ANALYSIS_UUID_2)));
131   }
132
133   private void createProjectMeasureForDeprecatedMetric(String metricUuid, String analysisUuid, String totalIssues) {
134     String uuid = UuidFactoryImpl.INSTANCE.create();
135     Map<String, Object> map = Map.ofEntries(
136       Map.entry("UUID", uuid),
137       Map.entry("TEXT_VALUE", "{\"LOW\":X,\"MEDIUM\":Y,\"HIGH\":Z,\"total\":" + totalIssues + "}"),
138       Map.entry("ANALYSIS_UUID", analysisUuid),
139       Map.entry("METRIC_UUID", metricUuid),
140       Map.entry("COMPONENT_UUID", UuidFactoryImpl.INSTANCE.create()));
141     db.executeInsert("project_measures", map);
142   }
143
144   private void createProjectMeasureForNewMetric(String metricUuid, String analysisUuid, int totalIssues) {
145     String uuid = UuidFactoryImpl.INSTANCE.create();
146     Map<String, Object> map = Map.ofEntries(
147       Map.entry("UUID", uuid),
148       Map.entry("VALUE", totalIssues),
149       Map.entry("ANALYSIS_UUID", analysisUuid),
150       Map.entry("METRIC_UUID", metricUuid),
151       Map.entry("COMPONENT_UUID", UuidFactoryImpl.INSTANCE.create()));
152     db.executeInsert("project_measures", map);
153   }
154
155   private Map<String, String> insertMetricsToMigrate() {
156     Map<String, String> createdMetrics = new HashMap<>();
157     MIGRATION_MAP.keySet().forEach(metricKey -> createdMetrics.put(metricKey, insertMetric(metricKey)));
158     return createdMetrics;
159   }
160
161   private Map<String, String> insertReplacementMetrics() {
162     Map<String, String> createdMetrics = new HashMap<>();
163     MIGRATION_MAP.values().forEach(metricKey -> createdMetrics.put(metricKey, insertMetric(metricKey)));
164     return createdMetrics;
165   }
166
167   private String insertMetric(String key) {
168     String uuid = UuidFactoryImpl.INSTANCE.create();
169     Map<String, Object> map = Map.ofEntries(
170       Map.entry("UUID", uuid),
171       Map.entry("NAME", key));
172     db.executeInsert("metrics", map);
173     return uuid;
174   }
175 }