You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RegisterQualityGatesTest.java 12KB

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