]> source.dussan.org Git - sonarqube.git/blob
4f5a81e57978de2212eb72fa878d6349cfe59c9a
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2016 SonarSource SA
4  * mailto:contact 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
21 package org.sonar.server.qualitygate;
22
23 import com.tngtech.java.junit.dataprovider.DataProvider;
24 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
25 import com.tngtech.java.junit.dataprovider.UseDataProvider;
26 import javax.annotation.Nullable;
27 import org.junit.Before;
28 import org.junit.Rule;
29 import org.junit.Test;
30 import org.junit.rules.ExpectedException;
31 import org.junit.runner.RunWith;
32 import org.sonar.api.measures.Metric;
33 import org.sonar.api.utils.System2;
34 import org.sonar.db.DbClient;
35 import org.sonar.db.DbSession;
36 import org.sonar.db.DbTester;
37 import org.sonar.db.metric.MetricDto;
38 import org.sonar.db.qualitygate.QualityGateConditionDto;
39 import org.sonar.db.qualitygate.QualityGateDbTester;
40 import org.sonar.db.qualitygate.QualityGateDto;
41 import org.sonar.server.exceptions.BadRequestException;
42 import org.sonar.server.exceptions.NotFoundException;
43
44 import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
45 import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
46 import static org.sonar.api.measures.Metric.ValueType.DATA;
47 import static org.sonar.api.measures.Metric.ValueType.INT;
48 import static org.sonar.api.measures.Metric.ValueType.RATING;
49 import static org.sonar.db.metric.MetricTesting.newMetricDto;
50 import static org.sonar.server.computation.task.projectanalysis.metric.Metric.MetricType.PERCENT;
51
52 @RunWith(DataProviderRunner.class)
53 public class QualityGateConditionsUpdaterTest {
54
55   @Rule
56   public ExpectedException expectedException = ExpectedException.none();
57
58   @Rule
59   public DbTester db = DbTester.create(System2.INSTANCE);
60
61   DbClient dbClient = db.getDbClient();
62   DbSession dbSession = db.getSession();
63   QualityGateDbTester qualityGateDbTester = new QualityGateDbTester(db);
64
65   QualityGateDto qualityGateDto;
66   MetricDto coverageMetricDto = newMetricDto()
67     .setKey("coverage")
68     .setShortName("Coverage")
69     .setValueType(PERCENT.name())
70     .setHidden(false);
71
72   MetricDto ratingMetricDto = newMetricDto()
73     .setKey("rating_metric")
74     .setShortName("Rating")
75     .setValueType(RATING.name())
76     .setHidden(false);
77
78   QualityGateConditionsUpdater underTest = new QualityGateConditionsUpdater(dbClient);
79
80   @Before
81   public void setUp() throws Exception {
82     qualityGateDto = qualityGateDbTester.insertQualityGate();
83     dbClient.metricDao().insert(dbSession, coverageMetricDto, ratingMetricDto);
84     dbSession.commit();
85   }
86
87   @Test
88   public void create_warning_condition_without_period() {
89     QualityGateConditionDto result = underTest.createCondition(dbSession, qualityGateDto.getId(), "coverage", "LT", "90", null, null);
90
91     verifyCondition(result, coverageMetricDto.getId(), "LT", "90", null, null);
92   }
93
94   @Test
95   public void create_error_condition_with_period() {
96     MetricDto metricDto = dbClient.metricDao().insert(dbSession, newMetricDto()
97       .setKey("new_coverage")
98       .setValueType(INT.name())
99       .setHidden(false));
100     dbSession.commit();
101
102     QualityGateConditionDto result = underTest.createCondition(dbSession, qualityGateDto.getId(), "new_coverage", "LT", null, "80", 1);
103
104     verifyCondition(result, metricDto.getId(), "LT", null, "80", 1);
105   }
106
107   @Test
108   public void fail_to_create_condition_when_condition_on_same_metric_already_exist() throws Exception {
109     dbClient.gateConditionDao().insert(new QualityGateConditionDto()
110       .setQualityGateId(qualityGateDto.getId())
111       .setMetricId(coverageMetricDto.getId())
112       .setPeriod(null),
113       dbSession);
114
115     expectedException.expect(BadRequestException.class);
116     expectedException.expectMessage("Condition on metric 'Coverage' already exists.");
117     underTest.createCondition(dbSession, qualityGateDto.getId(), coverageMetricDto.getKey(), "LT", "90", null, null);
118   }
119
120   @Test
121   public void fail_to_create_condition_when_condition_on_same_metric_and_on_leak_period_already_exist() throws Exception {
122     dbClient.gateConditionDao().insert(new QualityGateConditionDto()
123       .setQualityGateId(qualityGateDto.getId())
124       .setMetricId(coverageMetricDto.getId())
125       .setPeriod(1),
126       dbSession);
127
128     expectedException.expect(BadRequestException.class);
129     expectedException.expectMessage("Condition on metric 'Coverage' over leak period already exists.");
130     underTest.createCondition(dbSession, qualityGateDto.getId(), coverageMetricDto.getKey(), "LT", "90", null, 1);
131   }
132
133   @Test
134   public void fail_to_create_condition_on_missing_metric() {
135     expectedException.expect(NotFoundException.class);
136     expectedException.expectMessage("There is no metric with key=new_coverage");
137     underTest.createCondition(dbSession, qualityGateDto.getId(), "new_coverage", "LT", null, "80", 2);
138   }
139
140   @Test
141   @UseDataProvider("invalid_metrics")
142   public void fail_to_create_condition_on_invalid_metric(String metricKey, Metric.ValueType valueType, boolean hidden) {
143     dbClient.metricDao().insert(dbSession, newMetricDto()
144       .setKey(metricKey)
145       .setValueType(valueType.name())
146       .setHidden(hidden));
147     dbSession.commit();
148
149     expectedException.expect(BadRequestException.class);
150     expectedException.expectMessage("Metric '" + metricKey + "' cannot be used to define a condition.");
151     underTest.createCondition(dbSession, qualityGateDto.getId(), metricKey, "EQ", null, "80", null);
152   }
153
154   @Test
155   public void fail_to_create_condition_on_not_allowed_operator() {
156     expectedException.expect(BadRequestException.class);
157     expectedException.expectMessage("Operator UNKNOWN is not allowed for metric type PERCENT.");
158     underTest.createCondition(dbSession, qualityGateDto.getId(), "coverage", "UNKNOWN", null, "80", 2);
159   }
160
161   @Test
162   public void fail_to_create_condition_on_missing_period() {
163     dbClient.metricDao().insert(dbSession, newMetricDto()
164       .setKey("new_coverage")
165       .setValueType(INT.name())
166       .setHidden(false));
167     dbSession.commit();
168
169     expectedException.expect(BadRequestException.class);
170     expectedException.expectMessage("A period must be selected for differential metrics.");
171     underTest.createCondition(dbSession, qualityGateDto.getId(), "new_coverage", "EQ", null, "90", null);
172   }
173
174   @Test
175   public void fail_to_create_condition_on_invalid_period() {
176     expectedException.expect(BadRequestException.class);
177     expectedException.expectMessage("The only valid quality gate period is 1, the leak period.");
178     underTest.createCondition(dbSession, qualityGateDto.getId(), "coverage", "EQ", null, "90", 6);
179   }
180
181   @Test
182   public void create_condition_on_rating_metric() {
183     QualityGateConditionDto result = underTest.createCondition(dbSession, qualityGateDto.getId(), "rating_metric", "GT", null, "3", null);
184
185     verifyCondition(result, ratingMetricDto.getId(), "GT", null, "3", null);
186   }
187
188   @Test
189   public void fail_to_create_condition_on_rating_metric_on_leak_period() {
190     expectedException.expect(BadRequestException.class);
191     expectedException.expectMessage("The metric 'Rating' cannot be used on the leak period");
192     underTest.createCondition(dbSession, qualityGateDto.getId(), "rating_metric", "GT", null, "3", 1);
193   }
194
195   @Test
196   public void fail_to_create_warning_condition_on_invalid_rating_metric() {
197     expectedException.expect(BadRequestException.class);
198     expectedException.expectMessage("'6' is not a valid rating");
199     underTest.createCondition(dbSession, qualityGateDto.getId(), ratingMetricDto.getKey(), "GT", "6", null, null);
200   }
201
202   @Test
203   public void fail_to_create_error_condition_on_invalid_rating_metric() {
204     expectedException.expect(BadRequestException.class);
205     expectedException.expectMessage("'80' is not a valid rating");
206     underTest.createCondition(dbSession, qualityGateDto.getId(), ratingMetricDto.getKey(), "GT", null, "80", null);
207   }
208
209   @Test
210   public void fail_to_create_condition_on_greater_than_E() {
211     expectedException.expect(BadRequestException.class);
212     expectedException.expectMessage("There's no worse rating than E (5)");
213     underTest.createCondition(dbSession, qualityGateDto.getId(), ratingMetricDto.getKey(), "GT", "5", null, null);
214   }
215
216   @Test
217   public void update_condition() {
218     QualityGateConditionDto condition = insertCondition(coverageMetricDto.getId(), "LT", null, "80", null);
219
220     QualityGateConditionDto result = underTest.updateCondition(dbSession, condition.getId(), "coverage", "GT", "60", null, 1);
221
222     verifyCondition(result, coverageMetricDto.getId(), "GT", "60", null, 1);
223   }
224
225   @Test
226   public void update_condition_over_leak_period() {
227     QualityGateConditionDto condition = insertCondition(coverageMetricDto.getId(), "GT", "80", null, 1);
228
229     QualityGateConditionDto result = underTest.updateCondition(dbSession, condition.getId(), "coverage", "LT", null, "80", null);
230
231     verifyCondition(result, coverageMetricDto.getId(), "LT", null, "80", null);
232   }
233
234   @Test
235   public void update_condition_on_rating_metric() {
236     QualityGateConditionDto condition = insertCondition(ratingMetricDto.getId(), "LT", null, "3", null);
237
238     QualityGateConditionDto result = underTest.updateCondition(dbSession, condition.getId(), "rating_metric", "GT", "4", null, null);
239
240     verifyCondition(result, ratingMetricDto.getId(), "GT", "4", null, null);
241   }
242
243   @Test
244   public void fail_to_update_condition_on_rating_metric_on_leak_period() {
245     QualityGateConditionDto condition = insertCondition(ratingMetricDto.getId(), "LT", null, "3", null);
246
247     expectedException.expect(BadRequestException.class);
248     expectedException.expectMessage("The metric 'Rating' cannot be used on the leak period");
249     underTest.updateCondition(dbSession, condition.getId(), "rating_metric", "GT", "4", null, 1);
250   }
251
252   @Test
253   @UseDataProvider("invalid_metrics")
254   public void fail_to_update_condition_on_invalid_metric(String metricKey, Metric.ValueType valueType, boolean hidden) {
255     MetricDto metricDto = dbClient.metricDao().insert(dbSession, newMetricDto()
256       .setKey(metricKey)
257       .setValueType(valueType.name())
258       .setHidden(hidden));
259     QualityGateConditionDto condition = insertCondition(metricDto.getId(), "LT", null, "80", null);
260     dbSession.commit();
261
262     expectedException.expect(BadRequestException.class);
263     expectedException.expectMessage("Metric '" + metricKey + "' cannot be used to define a condition.");
264     underTest.updateCondition(dbSession, condition.getId(), metricDto.getKey(), "GT", "60", null, 1);
265   }
266
267   @Test
268   public void fail_to_update_condition_when_condition_on_same_metric_already_exist() throws Exception {
269     QualityGateConditionDto conditionNotOnLeakPeriod = insertCondition(coverageMetricDto.getId(), "GT", "80", null, null);
270     QualityGateConditionDto conditionOnLeakPeriod = insertCondition(coverageMetricDto.getId(), "GT", "80", null, 1);
271
272     expectedException.expect(BadRequestException.class);
273     expectedException.expectMessage("Condition on metric 'Coverage' over leak period already exists.");
274     // Update condition not on leak period to be on leak period => will fail as this condition already exist
275     underTest.updateCondition(dbSession, conditionNotOnLeakPeriod.getId(), coverageMetricDto.getKey(), "GT", "80", null, 1);
276   }
277
278   @DataProvider
279   public static Object[][] invalid_metrics() {
280     return new Object[][] {
281       {ALERT_STATUS_KEY, INT, false},
282       {"data_metric", DATA, false},
283       {"hidden", INT, true}
284     };
285   }
286
287   private QualityGateConditionDto insertCondition(long metricId, String operator, @Nullable String warning, @Nullable String error,
288     @Nullable Integer period) {
289     QualityGateConditionDto qualityGateConditionDto = new QualityGateConditionDto().setQualityGateId(qualityGateDto.getId())
290       .setMetricId(metricId)
291       .setOperator(operator)
292       .setWarningThreshold(warning)
293       .setErrorThreshold(error)
294       .setPeriod(period);
295     dbClient.gateConditionDao().insert(qualityGateConditionDto, dbSession);
296     dbSession.commit();
297     return qualityGateConditionDto;
298   }
299
300   private void verifyCondition(QualityGateConditionDto dto, int metricId, String operator, @Nullable String warning, @Nullable String error, @Nullable Integer period) {
301     QualityGateConditionDto reloaded = dbClient.gateConditionDao().selectById(dto.getId(), dbSession);
302     assertThat(reloaded.getQualityGateId()).isEqualTo(qualityGateDto.getId());
303     assertThat(reloaded.getMetricId()).isEqualTo(metricId);
304     assertThat(reloaded.getOperator()).isEqualTo(operator);
305     assertThat(reloaded.getWarningThreshold()).isEqualTo(warning);
306     assertThat(reloaded.getErrorThreshold()).isEqualTo(error);
307     assertThat(reloaded.getPeriod()).isEqualTo(period);
308
309     assertThat(dto.getQualityGateId()).isEqualTo(qualityGateDto.getId());
310     assertThat(dto.getMetricId()).isEqualTo(metricId);
311     assertThat(dto.getOperator()).isEqualTo(operator);
312     assertThat(dto.getWarningThreshold()).isEqualTo(warning);
313     assertThat(dto.getErrorThreshold()).isEqualTo(error);
314     assertThat(dto.getPeriod()).isEqualTo(period);
315   }
316
317 }