]> source.dussan.org Git - sonarqube.git/blob
4c0e18963720059dd95f88459f620ab444eee433
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2020 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.qualitygate;
21
22 import java.util.ArrayList;
23 import java.util.Date;
24 import java.util.List;
25 import java.util.Random;
26 import org.junit.Rule;
27 import org.junit.Test;
28 import org.sonar.api.utils.System2;
29 import org.sonar.api.utils.log.LogTester;
30 import org.sonar.api.utils.log.LoggerLevel;
31 import org.sonar.core.util.UuidFactoryFast;
32 import org.sonar.core.util.Uuids;
33 import org.sonar.db.DbClient;
34 import org.sonar.db.DbSession;
35 import org.sonar.db.DbTester;
36 import org.sonar.db.metric.MetricDao;
37 import org.sonar.db.metric.MetricDto;
38 import org.sonar.db.qualitygate.QualityGateConditionDao;
39 import org.sonar.db.qualitygate.QualityGateConditionDto;
40 import org.sonar.db.qualitygate.QualityGateDao;
41 import org.sonar.db.qualitygate.QualityGateDto;
42
43 import static org.assertj.core.api.Assertions.assertThat;
44 import static org.assertj.core.api.Assertions.tuple;
45 import static org.sonar.api.measures.CoreMetrics.NEW_COVERAGE_KEY;
46 import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_KEY;
47 import static org.sonar.api.measures.CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY;
48 import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY;
49 import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING_KEY;
50 import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT_KEY;
51 import static org.sonar.api.measures.Metric.ValueType.INT;
52 import static org.sonar.api.measures.Metric.ValueType.PERCENT;
53 import static org.sonar.db.metric.MetricTesting.newMetricDto;
54 import static org.sonar.db.qualitygate.QualityGateConditionDto.OPERATOR_GREATER_THAN;
55 import static org.sonar.db.qualitygate.QualityGateConditionDto.OPERATOR_LESS_THAN;
56
57 public class RegisterQualityGatesTest {
58
59   @Rule
60   public DbTester db = DbTester.create(System2.INSTANCE);
61   @Rule
62   public LogTester logTester = new LogTester();
63
64   private static final String BUILT_IN_NAME = "Sonar way";
65
66   private DbClient dbClient = db.getDbClient();
67   private DbSession dbSession = db.getSession();
68
69   private QualityGateDao qualityGateDao = dbClient.qualityGateDao();
70   private QualityGateConditionDao gateConditionDao = dbClient.gateConditionDao();
71   private MetricDao metricDao = dbClient.metricDao();
72   private QualityGateConditionsUpdater qualityGateConditionsUpdater = new QualityGateConditionsUpdater(dbClient);
73   private QualityGateFinder qualityGateFinder = new QualityGateFinder(dbClient);
74
75   private RegisterQualityGates underTest = new RegisterQualityGates(dbClient, qualityGateConditionsUpdater,
76     UuidFactoryFast.getInstance(), System2.INSTANCE);
77
78   @Test
79   public void register_default_gate() {
80     insertMetrics();
81
82     underTest.start();
83
84     verifyCorrectBuiltInQualityGate();
85     assertThat(
86       logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate [Sonar way] has been created")).isTrue();
87     assertThat(
88       logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue();
89   }
90
91   @Test
92   public void upgrade_empty_quality_gate() {
93     insertMetrics();
94
95     underTest.start();
96
97     assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1);
98     verifyCorrectBuiltInQualityGate();
99     assertThat(
100       logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue();
101   }
102
103   @Test
104   public void upgrade_should_remove_deleted_condition() {
105     insertMetrics();
106     QualityGateDto builtInQualityGate = db.qualityGates().insertBuiltInQualityGate();
107     createBuiltInConditions(builtInQualityGate);
108     // Add another condition
109     qualityGateConditionsUpdater.createCondition(dbSession, builtInQualityGate,
110       NEW_SECURITY_REMEDIATION_EFFORT_KEY, OPERATOR_GREATER_THAN, "5");
111     dbSession.commit();
112
113     underTest.start();
114
115     assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1);
116     verifyCorrectBuiltInQualityGate();
117     assertThat(
118       logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue();
119   }
120
121   @Test
122   public void upgrade_should_add_missing_condition() {
123     insertMetrics();
124     QualityGateDto builtInQualityGate = db.qualityGates().insertBuiltInQualityGate();
125     List<QualityGateConditionDto> builtInConditions = createBuiltInConditions(builtInQualityGate);
126     // Remove a condition
127     QualityGateConditionDto conditionToBeDeleted = builtInConditions.get(new Random().nextInt(builtInConditions.size()));
128     gateConditionDao.delete(conditionToBeDeleted, dbSession);
129     dbSession.commit();
130
131     underTest.start();
132
133     assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1);
134     verifyCorrectBuiltInQualityGate();
135     assertThat(
136       logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue();
137   }
138
139   @Test
140   public void should_set_SonarWay_as_builtin_when_not_set() {
141     insertMetrics();
142     QualityGateDto qualityGate = dbClient.qualityGateDao().insert(dbSession, new QualityGateDto()
143       .setName("Sonar way")
144       .setUuid(Uuids.createFast())
145       .setBuiltIn(false)
146       .setCreatedAt(new Date()));
147     dbSession.commit();
148     createBuiltInConditions(qualityGate);
149     dbSession.commit();
150
151     underTest.start();
152
153     assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1);
154     verifyCorrectBuiltInQualityGate();
155     assertThat(
156       logTester.logs(LoggerLevel.INFO).contains("Quality gate [Sonar way] has been set as built-in")).isTrue();
157   }
158
159   @Test
160   public void should_not_update_builtin_quality_gate_if_already_uptodate() {
161     insertMetrics();
162     QualityGateDto builtInQualityGate = db.qualityGates().insertBuiltInQualityGate();
163     createBuiltInConditions(builtInQualityGate);
164     dbSession.commit();
165
166     underTest.start();
167
168     assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1);
169     verifyCorrectBuiltInQualityGate();
170     // Log must not be present
171     assertThat(
172       logTester.logs(LoggerLevel.INFO).contains("Quality gate [Sonar way] has been set as built-in")).isFalse();
173     assertThat(
174       logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate [Sonar way] has been created")).isFalse();
175     assertThat(
176       logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isFalse();
177   }
178
179   @Test
180   public void ensure_only_one_built_in_quality_gate() {
181     insertMetrics();
182     String qualityGateName = "IncorrectQualityGate";
183     QualityGateDto builtin = new QualityGateDto().setName(qualityGateName).setBuiltIn(true).setUuid(Uuids.createFast());
184     qualityGateDao.insert(dbSession, builtin);
185     dbSession.commit();
186
187     underTest.start();
188
189     QualityGateDto oldQualityGate = qualityGateDao.selectByName(dbSession, qualityGateName);
190     assertThat(oldQualityGate).isNotNull();
191     assertThat(oldQualityGate.isBuiltIn()).isFalse();
192     assertThat(db.select("select name as \"name\" from quality_gates where is_built_in is true"))
193       .extracting(column -> column.get("name"))
194       .containsExactly(BUILT_IN_NAME);
195     assertThat(
196       logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate [Sonar way] has been created")).isTrue();
197     assertThat(
198       logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue();
199   }
200
201   @Test
202   public void ensure_only_that_builtin_is_set_as_default_when_no_default_quality_gate() {
203     insertMetrics();
204     QualityGateDto builtInQualityGate = db.qualityGates().insertBuiltInQualityGate();
205
206     underTest.start();
207
208     assertThat(qualityGateFinder.getBuiltInQualityGate(dbSession)).isNotNull();
209     assertThat(qualityGateFinder.getBuiltInQualityGate(dbSession).getId()).isEqualTo(builtInQualityGate.getId());
210   }
211
212   @Test
213   public void builtin_quality_gate_with_incorrect_metricId_should_not_throw_an_exception() {
214     insertMetrics();
215     QualityGateConditionDto conditionDto = new QualityGateConditionDto()
216       .setMetricId(-1) // This Id does not exist
217       .setOperator(OPERATOR_GREATER_THAN)
218       .setErrorThreshold("1");
219     gateConditionDao.insert(conditionDto, dbSession);
220     dbSession.commit();
221
222     underTest.start();
223
224     // No exception thrown
225     verifyCorrectBuiltInQualityGate();
226     assertThat(
227       logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue();
228   }
229
230   private void insertMetrics() {
231     dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_RELIABILITY_RATING_KEY).setValueType(INT.name()).setHidden(false).setDirection(0));
232     dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_SECURITY_RATING_KEY).setValueType(INT.name()).setHidden(false).setDirection(0));
233     dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_SECURITY_REMEDIATION_EFFORT_KEY).setValueType(INT.name()).setHidden(false).setDirection(0));
234     dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_MAINTAINABILITY_RATING_KEY).setValueType(PERCENT.name()).setHidden(false).setDirection(0));
235     dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_COVERAGE_KEY).setValueType(PERCENT.name()).setHidden(false).setDirection(0));
236     dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_DUPLICATED_LINES_DENSITY_KEY).setValueType(PERCENT.name()).setHidden(false).setDirection(0));
237     dbSession.commit();
238   }
239
240   private void verifyCorrectBuiltInQualityGate() {
241     MetricDto newReliability = metricDao.selectByKey(dbSession, NEW_RELIABILITY_RATING_KEY);
242     MetricDto newSecurity = metricDao.selectByKey(dbSession, NEW_SECURITY_RATING_KEY);
243     MetricDto newMaintainability = metricDao.selectByKey(dbSession, NEW_MAINTAINABILITY_RATING_KEY);
244     MetricDto newCoverage = metricDao.selectByKey(dbSession, NEW_COVERAGE_KEY);
245     MetricDto newDuplication = metricDao.selectByKey(dbSession, NEW_DUPLICATED_LINES_DENSITY_KEY);
246
247     QualityGateDto qualityGateDto = qualityGateDao.selectByName(dbSession, BUILT_IN_NAME);
248     assertThat(qualityGateDto).isNotNull();
249     assertThat(qualityGateDto.getCreatedAt()).isNotNull();
250     assertThat(qualityGateDto.isBuiltIn()).isTrue();
251     assertThat(gateConditionDao.selectForQualityGate(dbSession, qualityGateDto.getId()))
252       .extracting(QualityGateConditionDto::getMetricId, QualityGateConditionDto::getOperator,
253         QualityGateConditionDto::getErrorThreshold)
254       .containsOnly(
255         tuple(newReliability.getId().longValue(), OPERATOR_GREATER_THAN, "1"),
256         tuple(newSecurity.getId().longValue(), OPERATOR_GREATER_THAN, "1"),
257         tuple(newMaintainability.getId().longValue(), OPERATOR_GREATER_THAN, "1"),
258         tuple(newCoverage.getId().longValue(), OPERATOR_LESS_THAN, "80"),
259         tuple(newDuplication.getId().longValue(), OPERATOR_GREATER_THAN, "3"));
260   }
261
262   private List<QualityGateConditionDto> createBuiltInConditions(QualityGateDto qg) {
263     List<QualityGateConditionDto> conditions = new ArrayList<>();
264
265     conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg,
266       NEW_SECURITY_RATING_KEY, OPERATOR_GREATER_THAN, "1"));
267     conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg,
268       NEW_RELIABILITY_RATING_KEY, OPERATOR_GREATER_THAN, "1"));
269     conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg,
270       NEW_MAINTAINABILITY_RATING_KEY, OPERATOR_GREATER_THAN, "1"));
271     conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg,
272       NEW_COVERAGE_KEY, OPERATOR_LESS_THAN, "80"));
273     conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg,
274       NEW_DUPLICATED_LINES_DENSITY_KEY, OPERATOR_GREATER_THAN, "3"));
275
276     return conditions;
277   }
278 }