]> source.dussan.org Git - sonarqube.git/blob
3b855a3be86b64e4625d64ef6a076876428b5b30
[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.ce.task.projectanalysis.step;
21
22 import java.util.Optional;
23 import org.junit.Before;
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.sonar.api.measures.Metric;
27 import org.sonar.api.utils.System2;
28 import org.sonar.ce.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule;
29 import org.sonar.ce.task.projectanalysis.component.Component;
30 import org.sonar.ce.task.projectanalysis.component.ReportComponent;
31 import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
32 import org.sonar.ce.task.projectanalysis.component.ViewsComponent;
33 import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
34 import org.sonar.ce.task.projectanalysis.measure.MeasureToMeasureDto;
35 import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
36 import org.sonar.ce.task.step.ComputationStep;
37 import org.sonar.ce.task.step.TestComputationStepContext;
38 import org.sonar.db.DbClient;
39 import org.sonar.db.DbTester;
40 import org.sonar.db.component.ComponentDto;
41 import org.sonar.db.measure.MeasureDto;
42 import org.sonar.db.metric.MetricDto;
43
44 import static org.assertj.core.api.Assertions.assertThat;
45 import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY;
46 import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
47 import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
48 import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT_VIEW;
49 import static org.sonar.ce.task.projectanalysis.component.Component.Type.SUBVIEW;
50 import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW;
51 import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
52
53 public class PersistMeasuresStepIT extends BaseStepTest {
54
55   private static final Metric STRING_METRIC = new Metric.Builder("string-metric", "String metric", Metric.ValueType.STRING).create();
56   private static final Metric INT_METRIC = new Metric.Builder("int-metric", "int metric", Metric.ValueType.INT).create();
57   private static final Metric NON_HISTORICAL_METRIC = new Metric.Builder("nh-metric", "nh metric", Metric.ValueType.INT).setDeleteHistoricalData(true).create();
58
59   private static final String ANALYSIS_UUID = "a1";
60
61   private static final int REF_1 = 1;
62   private static final int REF_2 = 2;
63   private static final int REF_3 = 3;
64   private static final int REF_4 = 4;
65
66   @Rule
67   public DbTester db = DbTester.create(System2.INSTANCE);
68   @Rule
69   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
70   @Rule
71   public MetricRepositoryRule metricRepository = new MetricRepositoryRule();
72   @Rule
73   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
74   @Rule
75   public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule();
76
77   private DbClient dbClient = db.getDbClient();
78
79   @Before
80   public void setUp() {
81     analysisMetadataHolder.setUuid(ANALYSIS_UUID);
82     MetricDto stringMetricDto = db.measures().insertMetric(m -> m.setKey(STRING_METRIC.getKey()).setValueType(Metric.ValueType.STRING.name()));
83     MetricDto intMetricDto = db.measures().insertMetric(m -> m.setKey(INT_METRIC.getKey()).setValueType(Metric.ValueType.INT.name()));
84     MetricDto nhMetricDto = db.measures().insertMetric(m -> m.setKey(NON_HISTORICAL_METRIC.getKey()).setValueType(Metric.ValueType.INT.name()));
85     metricRepository.add(stringMetricDto.getUuid(), STRING_METRIC);
86     metricRepository.add(intMetricDto.getUuid(), INT_METRIC);
87     metricRepository.add(nhMetricDto.getUuid(), NON_HISTORICAL_METRIC);
88   }
89
90   @Test
91   public void measures_on_non_historical_metrics_are_not_persisted() {
92     prepareProject();
93     measureRepository.addRawMeasure(REF_1, NON_HISTORICAL_METRIC.getKey(), newMeasureBuilder().create(1));
94     measureRepository.addRawMeasure(REF_1, INT_METRIC.getKey(), newMeasureBuilder().create(2));
95
96     TestComputationStepContext context = execute();
97
98     assertThatMeasureIsNotPersisted("project-uuid", NON_HISTORICAL_METRIC);
99     MeasureDto persistedMeasure = selectMeasure("project-uuid", INT_METRIC).get();
100     assertThat(persistedMeasure.getValue()).isEqualTo(2);
101     assertNbOfInserts(context, 1);
102   }
103
104   @Test
105   public void persist_measures_of_project_analysis_excluding_directories() {
106     prepareProject();
107
108     // the computed measures
109     measureRepository.addRawMeasure(REF_1, STRING_METRIC.getKey(), newMeasureBuilder().create("project-value"));
110     measureRepository.addRawMeasure(REF_3, STRING_METRIC.getKey(), newMeasureBuilder().create("dir-value"));
111     measureRepository.addRawMeasure(REF_4, STRING_METRIC.getKey(), newMeasureBuilder().create("file-value"));
112
113     TestComputationStepContext context = execute();
114
115     // project and dir measures are persisted, but not file measures
116     assertThat(db.countRowsOfTable("project_measures")).isOne();
117     assertThat(selectMeasure("project-uuid", STRING_METRIC).get().getData()).isEqualTo("project-value");
118     assertThatMeasuresAreNotPersisted("dir-uuid");
119     assertThatMeasuresAreNotPersisted("file-uuid");
120     assertNbOfInserts(context, 1);
121   }
122
123   @Test
124   public void measures_without_value_are_not_persisted() {
125     prepareProject();
126     measureRepository.addRawMeasure(REF_1, STRING_METRIC.getKey(), newMeasureBuilder().createNoValue());
127     measureRepository.addRawMeasure(REF_1, INT_METRIC.getKey(), newMeasureBuilder().createNoValue());
128
129     TestComputationStepContext context = execute();
130
131     assertThatMeasureIsNotPersisted("project-uuid", STRING_METRIC);
132     assertThatMeasureIsNotPersisted("project-uuid", INT_METRIC);
133     assertNbOfInserts(context, 0);
134   }
135
136   @Test
137   public void measures_on_new_code_period_are_persisted() {
138     prepareProject();
139     measureRepository.addRawMeasure(REF_1, INT_METRIC.getKey(), newMeasureBuilder().create(42.0));
140
141     TestComputationStepContext context = execute();
142
143     MeasureDto persistedMeasure = selectMeasure("project-uuid", INT_METRIC).get();
144     assertThat(persistedMeasure.getValue()).isEqualTo(42.0);
145     assertNbOfInserts(context, 1);
146   }
147
148   @Test
149   public void persist_all_measures_of_portfolio_analysis() {
150     preparePortfolio();
151
152     // the computed measures
153     measureRepository.addRawMeasure(REF_1, STRING_METRIC.getKey(), newMeasureBuilder().create("view-value"));
154     measureRepository.addRawMeasure(REF_2, STRING_METRIC.getKey(), newMeasureBuilder().create("subview-value"));
155     measureRepository.addRawMeasure(REF_3, STRING_METRIC.getKey(), newMeasureBuilder().create("project-value"));
156
157     TestComputationStepContext context = execute();
158
159     assertThat(db.countRowsOfTable("project_measures")).isEqualTo(2);
160     assertThat(selectMeasure("view-uuid", STRING_METRIC).get().getData()).isEqualTo("view-value");
161     assertThat(selectMeasure("subview-uuid", STRING_METRIC).get().getData()).isEqualTo("subview-value");
162     assertNbOfInserts(context, 2);
163   }
164
165   private void prepareProject() {
166     // tree of components as defined by scanner report
167     Component project = ReportComponent.builder(PROJECT, REF_1).setUuid("project-uuid")
168       .addChildren(
169         ReportComponent.builder(DIRECTORY, REF_3).setUuid("dir-uuid")
170           .addChildren(
171             ReportComponent.builder(FILE, REF_4).setUuid("file-uuid")
172               .build())
173           .build())
174       .build();
175     treeRootHolder.setRoot(project);
176
177     // components as persisted in db
178     ComponentDto projectDto = insertComponent("project-key", "project-uuid");
179     ComponentDto dirDto = insertComponent("dir-key", "dir-uuid");
180     ComponentDto fileDto = insertComponent("file-key", "file-uuid");
181     db.components().insertSnapshot(projectDto, s -> s.setUuid(ANALYSIS_UUID));
182   }
183
184   private void preparePortfolio() {
185     // tree of components
186     Component portfolio = ViewsComponent.builder(VIEW, REF_1).setUuid("view-uuid")
187       .addChildren(
188         ViewsComponent.builder(SUBVIEW, REF_2).setUuid("subview-uuid")
189           .addChildren(
190             ViewsComponent.builder(PROJECT_VIEW, REF_3).setUuid("project-uuid")
191               .build())
192           .build())
193       .build();
194     treeRootHolder.setRoot(portfolio);
195
196     // components as persisted in db
197     ComponentDto viewDto = insertComponent("view-key", "view-uuid");
198     ComponentDto subViewDto = insertComponent("subview-key", "subview-uuid");
199     ComponentDto projectDto = insertComponent("project-key", "project-uuid");
200     db.components().insertSnapshot(viewDto, s -> s.setUuid(ANALYSIS_UUID));
201   }
202
203   private void assertThatMeasureIsNotPersisted(String componentUuid, Metric metric) {
204     assertThat(selectMeasure(componentUuid, metric)).isEmpty();
205   }
206
207   private void assertThatMeasuresAreNotPersisted(String componentUuid) {
208     assertThatMeasureIsNotPersisted(componentUuid, STRING_METRIC);
209     assertThatMeasureIsNotPersisted(componentUuid, INT_METRIC);
210   }
211
212   private TestComputationStepContext execute() {
213     TestComputationStepContext context = new TestComputationStepContext();
214     new PersistMeasuresStep(dbClient, metricRepository, new MeasureToMeasureDto(analysisMetadataHolder, treeRootHolder), treeRootHolder, measureRepository)
215       .execute(context);
216     return context;
217   }
218
219   private Optional<MeasureDto> selectMeasure(String componentUuid, Metric metric) {
220     return dbClient.measureDao().selectMeasure(db.getSession(), ANALYSIS_UUID, componentUuid, metric.getKey());
221   }
222
223   private ComponentDto insertComponent(String key, String uuid) {
224     ComponentDto componentDto = new ComponentDto()
225       .setKey(key)
226       .setUuid(uuid)
227       .setUuidPath(uuid + ".")
228       .setBranchUuid(uuid);
229     db.components().insertComponent(componentDto);
230     return componentDto;
231   }
232
233   private static void assertNbOfInserts(TestComputationStepContext context, int expected) {
234     context.getStatistics().assertValue("inserts", expected);
235   }
236
237   @Override
238   protected ComputationStep step() {
239     return new PersistMeasuresStep(dbClient, metricRepository, new MeasureToMeasureDto(analysisMetadataHolder, treeRootHolder), treeRootHolder, measureRepository);
240   }
241 }