]> source.dussan.org Git - sonarqube.git/blob
bd2dc92bb51be3f84910ae9c70a3ecac0856e506
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2019 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 com.tngtech.java.junit.dataprovider.DataProvider;
23 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
24 import com.tngtech.java.junit.dataprovider.UseDataProvider;
25 import javax.annotation.Nullable;
26 import org.junit.Rule;
27 import org.junit.Test;
28 import org.junit.rules.ExpectedException;
29 import org.junit.runner.RunWith;
30 import org.sonar.api.measures.Metric;
31 import org.sonar.api.utils.System2;
32 import org.sonar.db.DbTester;
33 import org.sonar.db.metric.MetricDto;
34 import org.sonar.db.qualitygate.QualityGateConditionDto;
35 import org.sonar.db.qualitygate.QualityGateDto;
36 import org.sonar.server.exceptions.BadRequestException;
37 import org.sonar.server.exceptions.NotFoundException;
38
39 import static java.lang.String.format;
40 import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
41 import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
42 import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY;
43 import static org.sonar.api.measures.Metric.ValueType.BOOL;
44 import static org.sonar.api.measures.Metric.ValueType.DATA;
45 import static org.sonar.api.measures.Metric.ValueType.FLOAT;
46 import static org.sonar.api.measures.Metric.ValueType.INT;
47 import static org.sonar.api.measures.Metric.ValueType.MILLISEC;
48 import static org.sonar.api.measures.Metric.ValueType.PERCENT;
49 import static org.sonar.api.measures.Metric.ValueType.RATING;
50 import static org.sonar.api.measures.Metric.ValueType.WORK_DUR;
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   private QualityGateConditionsUpdater underTest = new QualityGateConditionsUpdater(db.getDbClient());
62
63   @Test
64   public void create_error_condition() {
65     MetricDto metric = db.measures().insertMetric(m -> m.setKey("new_coverage").setValueType(INT.name()).setHidden(false));
66     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
67
68     QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", null, "80");
69
70     verifyCondition(result, qualityGate, metric, "LT", null, "80");
71   }
72
73   @Test
74   public void fail_to_create_condition_when_condition_on_same_metric_already_exist() {
75     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false));
76     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
77     db.qualityGates().addCondition(qualityGate, metric);
78
79     expectedException.expect(BadRequestException.class);
80     expectedException.expectMessage(format("Condition on metric '%s' already exists.", metric.getShortName()));
81
82     underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "90", null);
83   }
84
85   @Test
86   public void fail_to_create_condition_on_missing_metric() {
87     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
88
89     expectedException.expect(NotFoundException.class);
90     expectedException.expectMessage("There is no metric with key=new_coverage");
91
92     underTest.createCondition(db.getSession(), qualityGate, "new_coverage", "LT", null, "80");
93   }
94
95   @Test
96   @UseDataProvider("invalid_metrics")
97   public void fail_to_create_condition_on_invalid_metric(String metricKey, Metric.ValueType valueType, boolean hidden) {
98     MetricDto metric = db.measures().insertMetric(m -> m.setKey(metricKey).setValueType(valueType.name()).setHidden(hidden));
99     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
100
101     expectedException.expect(BadRequestException.class);
102     expectedException.expectMessage(format("Metric '%s' cannot be used to define a condition.", metric.getKey()));
103
104     underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, "80");
105   }
106
107   @Test
108   public void fail_to_create_condition_on_not_allowed_operator() {
109     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false));
110     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
111
112     expectedException.expect(BadRequestException.class);
113     expectedException.expectMessage("Operator UNKNOWN is not allowed for metric type PERCENT.");
114
115     underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "UNKNOWN", null, "80");
116   }
117
118   @Test
119   public void create_condition_on_rating_metric() {
120     MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
121     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
122
123     QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "3");
124
125     verifyCondition(result, qualityGate, metric, "GT", null, "3");
126   }
127
128   @Test
129   public void fail_to_create_warning_condition_on_invalid_rating_metric() {
130     MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
131     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
132
133     expectedException.expect(BadRequestException.class);
134     expectedException.expectMessage("'6' is not a valid rating");
135
136     underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "6", null);
137   }
138
139   @Test
140   public void fail_to_create_error_condition_on_invalid_rating_metric() {
141     MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
142     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
143
144     expectedException.expect(BadRequestException.class);
145     expectedException.expectMessage("'80' is not a valid rating");
146
147     underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "80");
148   }
149
150   @Test
151   public void fail_to_create_condition_on_greater_than_E() {
152     MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
153     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
154
155     expectedException.expect(BadRequestException.class);
156     expectedException.expectMessage("There's no worse rating than E (5)");
157
158     underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "5", null);
159   }
160
161   @Test
162   @UseDataProvider("valid_values")
163   public void create_warning_condition(Metric.ValueType valueType, String value) {
164     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
165     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
166
167     QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", value, null);
168
169     verifyCondition(result, qualityGate, metric, "EQ", value, null);
170   }
171
172   @Test
173   @UseDataProvider("valid_values")
174   public void create_error_condition(Metric.ValueType valueType, String value) {
175     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
176     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
177
178     QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, value);
179
180     verifyCondition(result, qualityGate, metric, "EQ", null, value);
181   }
182
183   @Test
184   @UseDataProvider("invalid_values")
185   public void fail_to_create_warning_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) {
186     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
187     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
188
189     expectedException.expect(BadRequestException.class);
190     expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
191
192     underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", value, null);
193   }
194
195   @Test
196   @UseDataProvider("invalid_values")
197   public void fail_to_create_error_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) {
198     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
199     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
200
201     expectedException.expect(BadRequestException.class);
202     expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
203
204     underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, value);
205   }
206
207   @Test
208   public void update_condition() {
209     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false));
210     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
211     QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
212       c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80"));
213
214     QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60", null);
215
216     verifyCondition(result, qualityGate, metric, "GT", "60", null);
217   }
218
219   @Test
220   public void update_condition_on_rating_metric() {
221     MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
222     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
223     QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
224       c -> c.setOperator("LT").setWarningThreshold("80").setErrorThreshold(null));
225
226     QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null);
227
228     verifyCondition(result, qualityGate, metric, "GT", "4", null);
229   }
230
231   @Test
232   public void fail_to_update_condition_on_rating_metric_on_not_core_rating_metric() {
233     MetricDto metric = db.measures().insertMetric(m -> m.setKey("not_core_rating_metric").setValueType(RATING.name()).setHidden(false));
234     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
235     QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
236       c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("3"));
237
238     expectedException.expect(BadRequestException.class);
239     expectedException.expectMessage(format("The metric '%s' cannot be used", metric.getShortName()));
240
241     underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null);
242   }
243
244   @Test
245   @UseDataProvider("invalid_metrics")
246   public void fail_to_update_condition_on_invalid_metric(String metricKey, Metric.ValueType valueType, boolean hidden) {
247     MetricDto metric = db.measures().insertMetric(m -> m.setKey(metricKey).setValueType(valueType.name()).setHidden(hidden));
248     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
249     QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
250       c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80"));
251
252     expectedException.expect(BadRequestException.class);
253     expectedException.expectMessage(format("Metric '%s' cannot be used to define a condition.", metric.getKey()));
254
255     underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60", null);
256   }
257
258   @Test
259   @UseDataProvider("valid_values")
260   public void update_warning_condition(Metric.ValueType valueType, String value) {
261     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
262     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
263     QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
264       c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80"));
265
266     QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value, null);
267
268     verifyCondition(result, qualityGate, metric, "EQ", value, null);
269   }
270
271   @Test
272   @UseDataProvider("valid_values")
273   public void update_error_condition(Metric.ValueType valueType, String value) {
274     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
275     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
276     QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
277       c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80"));
278
279     QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", null, value);
280
281     verifyCondition(result, qualityGate, metric, "EQ", null, value);
282   }
283
284   @Test
285   @UseDataProvider("invalid_values")
286   public void fail_to_update_warning_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) {
287     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
288     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
289     QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
290       c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80"));
291
292     expectedException.expect(BadRequestException.class);
293     expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
294
295     underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value, null);
296   }
297
298   @Test
299   @UseDataProvider("invalid_values")
300   public void fail_to_update_error_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) {
301     MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
302     QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
303     QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
304       c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80"));
305
306     expectedException.expect(BadRequestException.class);
307     expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
308
309     underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", null, value);
310   }
311
312   @DataProvider
313   public static Object[][] invalid_metrics() {
314     return new Object[][] {
315       {ALERT_STATUS_KEY, INT, false},
316       {"data_metric", DATA, false},
317       {"hidden", INT, true}
318     };
319   }
320
321   @DataProvider
322   public static Object[][] valid_values() {
323     return new Object[][] {
324       {INT, "10"},
325       {BOOL, "1"},
326       {MILLISEC, "1000"},
327       {WORK_DUR, "1000"},
328       {FLOAT, "5.12"},
329       {PERCENT, "10.30"},
330     };
331   }
332
333   @DataProvider
334   public static Object[][] invalid_values() {
335     return new Object[][] {
336       {INT, "ABCD"},
337       {BOOL, "ABCD"},
338       {MILLISEC, "ABCD"},
339       {WORK_DUR, "ABCD"},
340       {FLOAT, "ABCD"},
341       {PERCENT, "ABCD"},
342     };
343   }
344
345   private void verifyCondition(QualityGateConditionDto dto, QualityGateDto qualityGate, MetricDto metric, String operator, @Nullable String warning, @Nullable String error) {
346     QualityGateConditionDto reloaded = db.getDbClient().gateConditionDao().selectById(dto.getId(), db.getSession());
347     assertThat(reloaded.getQualityGateId()).isEqualTo(qualityGate.getId());
348     assertThat(reloaded.getMetricId()).isEqualTo(metric.getId().longValue());
349     assertThat(reloaded.getOperator()).isEqualTo(operator);
350     assertThat(reloaded.getWarningThreshold()).isEqualTo(warning);
351     assertThat(reloaded.getErrorThreshold()).isEqualTo(error);
352
353     assertThat(dto.getQualityGateId()).isEqualTo(qualityGate.getId());
354     assertThat(dto.getMetricId()).isEqualTo(metric.getId().longValue());
355     assertThat(dto.getOperator()).isEqualTo(operator);
356     assertThat(dto.getWarningThreshold()).isEqualTo(warning);
357     assertThat(dto.getErrorThreshold()).isEqualTo(error);
358   }
359
360 }