3 * Copyright (C) 2009-2017 SonarSource SA
4 * mailto:info AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.server.computation.task.projectanalysis.qualitygate;
22 import com.google.common.base.Optional;
23 import com.google.common.collect.ImmutableList;
24 import java.util.Collections;
25 import java.util.Random;
26 import org.apache.commons.lang.RandomStringUtils;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.sonar.api.measures.CoreMetrics;
30 import org.sonar.db.DbClient;
31 import org.sonar.db.DbSession;
32 import org.sonar.db.qualitygate.QualityGateConditionDao;
33 import org.sonar.db.qualitygate.QualityGateConditionDto;
34 import org.sonar.db.qualitygate.QualityGateDao;
35 import org.sonar.db.qualitygate.QualityGateDto;
36 import org.sonar.server.computation.task.projectanalysis.metric.Metric;
37 import org.sonar.server.computation.task.projectanalysis.metric.MetricImpl;
38 import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository;
39 import org.sonar.server.qualitygate.ShortLivingBranchQualityGate;
41 import static org.assertj.core.api.Assertions.assertThat;
42 import static org.assertj.core.api.Assertions.tuple;
43 import static org.assertj.guava.api.Assertions.assertThat;
44 import static org.mockito.Matchers.any;
45 import static org.mockito.Matchers.eq;
46 import static org.mockito.Mockito.mock;
47 import static org.mockito.Mockito.when;
48 import static org.sonar.server.computation.task.projectanalysis.qualitygate.Condition.Operator.GREATER_THAN;
50 public class QualityGateServiceImplTest {
51 private static final long SOME_ID = 123;
52 private static final String SOME_NAME = "some name";
53 private static final QualityGateDto QUALITY_GATE_DTO = new QualityGateDto().setId(SOME_ID).setName(SOME_NAME);
54 private static final long METRIC_ID_1 = 951;
55 private static final long METRIC_ID_2 = 753;
56 private static final Metric METRIC_1 = mock(Metric.class);
57 private static final Metric METRIC_2 = mock(Metric.class);
58 private static final QualityGateConditionDto CONDITION_1 = new QualityGateConditionDto().setId(321).setMetricId(METRIC_ID_1).setOperator("EQ").setPeriod(1)
59 .setWarningThreshold("warnin_th").setErrorThreshold("error_th");
60 private static final QualityGateConditionDto CONDITION_2 = new QualityGateConditionDto().setId(456).setMetricId(METRIC_ID_2).setOperator("NE");
62 private QualityGateDao qualityGateDao = mock(QualityGateDao.class);
63 private QualityGateConditionDao qualityGateConditionDao = mock(QualityGateConditionDao.class);
64 private MetricRepository metricRepository = mock(MetricRepository.class);
65 private DbClient dbClient = mock(DbClient.class);
66 private QualityGateServiceImpl underTest = new QualityGateServiceImpl(dbClient, metricRepository);
69 public void setUp() throws Exception {
70 when(dbClient.qualityGateDao()).thenReturn(qualityGateDao);
71 when(dbClient.gateConditionDao()).thenReturn(qualityGateConditionDao);
75 public void findById_returns_absent_when_QualityGateDto_does_not_exist() {
76 assertThat(underTest.findById(SOME_ID)).isAbsent();
80 public void findById_returns_QualityGate_with_empty_set_of_conditions_when_there_is_none_in_DB() {
81 when(qualityGateDao.selectById(any(DbSession.class), eq(SOME_ID))).thenReturn(QUALITY_GATE_DTO);
82 when(qualityGateConditionDao.selectForQualityGate(any(DbSession.class), eq(SOME_ID))).thenReturn(Collections.emptyList());
84 Optional<QualityGate> res = underTest.findById(SOME_ID);
86 assertThat(res).isPresent();
87 assertThat(res.get().getId()).isEqualTo(SOME_ID);
88 assertThat(res.get().getName()).isEqualTo(SOME_NAME);
89 assertThat(res.get().getConditions()).isEmpty();
93 public void findById_returns_conditions_when_there_is_some_in_DB() {
94 when(qualityGateDao.selectById(any(DbSession.class), eq(SOME_ID))).thenReturn(QUALITY_GATE_DTO);
95 when(qualityGateConditionDao.selectForQualityGate(any(DbSession.class), eq(SOME_ID))).thenReturn(ImmutableList.of(CONDITION_1, CONDITION_2));
96 // metrics are always supposed to be there
97 when(metricRepository.getOptionalById(METRIC_ID_1)).thenReturn(java.util.Optional.of(METRIC_1));
98 when(metricRepository.getOptionalById(METRIC_ID_2)).thenReturn(java.util.Optional.of(METRIC_2));
100 Optional<QualityGate> res = underTest.findById(SOME_ID);
102 assertThat(res).isPresent();
103 assertThat(res.get().getId()).isEqualTo(SOME_ID);
104 assertThat(res.get().getName()).isEqualTo(SOME_NAME);
105 assertThat(res.get().getConditions()).containsOnly(
106 new Condition(METRIC_1, CONDITION_1.getOperator(), CONDITION_1.getErrorThreshold(), CONDITION_1.getWarningThreshold(), true),
107 new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold(), CONDITION_2.getWarningThreshold(), false));
111 public void findById_ignores_conditions_on_missing_metrics() {
112 when(qualityGateDao.selectById(any(DbSession.class), eq(SOME_ID))).thenReturn(QUALITY_GATE_DTO);
113 when(qualityGateConditionDao.selectForQualityGate(any(DbSession.class), eq(SOME_ID))).thenReturn(ImmutableList.of(CONDITION_1, CONDITION_2));
114 // metrics are always supposed to be there
115 when(metricRepository.getOptionalById(METRIC_ID_1)).thenReturn(java.util.Optional.empty());
116 when(metricRepository.getOptionalById(METRIC_ID_2)).thenReturn(java.util.Optional.of(METRIC_2));
118 Optional<QualityGate> res = underTest.findById(SOME_ID);
120 assertThat(res).isPresent();
121 assertThat(res.get().getId()).isEqualTo(SOME_ID);
122 assertThat(res.get().getName()).isEqualTo(SOME_NAME);
123 assertThat(res.get().getConditions()).containsOnly(
124 new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold(), CONDITION_2.getWarningThreshold(), false));
128 public void findById_of_hardcoded_short_living_branch_returns_hardcoded_qp() {
129 MetricImpl bugsMetric = mockMetricInRepository(CoreMetrics.BUGS_KEY);
130 MetricImpl vulnerabilitiesMetric = mockMetricInRepository(CoreMetrics.VULNERABILITIES_KEY);
131 MetricImpl codeSmellsMetric = mockMetricInRepository(CoreMetrics.CODE_SMELLS_KEY);
133 Optional<QualityGate> res = underTest.findById(ShortLivingBranchQualityGate.ID);
135 assertThat(res).isPresent();
136 QualityGate qualityGate = res.get();
137 assertThat(qualityGate.getId()).isEqualTo(ShortLivingBranchQualityGate.ID);
138 assertThat(qualityGate.getName()).isEqualTo("Hardcoded short living branch quality gate");
139 assertThat(qualityGate.getConditions())
140 .extracting(Condition::getMetric, Condition::getOperator, Condition::getErrorThreshold, Condition::getWarningThreshold, Condition::hasPeriod)
142 tuple(bugsMetric, GREATER_THAN, "0", null, false),
143 tuple(vulnerabilitiesMetric, GREATER_THAN, "0", null, false),
144 tuple(codeSmellsMetric, GREATER_THAN, "0", null, false));
147 private MetricImpl mockMetricInRepository(String metricKey) {
148 MetricImpl metric = new MetricImpl(new Random().nextInt(999), metricKey, RandomStringUtils.randomAlphanumeric(20), Metric.MetricType.INT);
149 when(metricRepository.getByKey(metricKey))