Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

QualityGateEventsStepTest.java 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  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.ce.task.projectanalysis.step;
  21. import java.util.Optional;
  22. import java.util.Random;
  23. import org.junit.Before;
  24. import org.junit.Rule;
  25. import org.junit.Test;
  26. import org.mockito.ArgumentCaptor;
  27. import org.sonar.api.notifications.Notification;
  28. import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
  29. import org.sonar.ce.task.projectanalysis.analysis.Branch;
  30. import org.sonar.ce.task.projectanalysis.component.Component;
  31. import org.sonar.ce.task.projectanalysis.component.DefaultBranchImpl;
  32. import org.sonar.ce.task.projectanalysis.component.ReportComponent;
  33. import org.sonar.ce.task.projectanalysis.component.TreeRootHolder;
  34. import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
  35. import org.sonar.ce.task.projectanalysis.event.Event;
  36. import org.sonar.ce.task.projectanalysis.event.EventRepository;
  37. import org.sonar.ce.task.projectanalysis.measure.Measure;
  38. import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
  39. import org.sonar.ce.task.projectanalysis.measure.QualityGateStatus;
  40. import org.sonar.ce.task.projectanalysis.metric.Metric;
  41. import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
  42. import org.sonar.ce.task.step.TestComputationStepContext;
  43. import org.sonar.db.component.BranchType;
  44. import org.sonar.server.notification.NotificationService;
  45. import org.sonar.server.project.Project;
  46. import static java.util.Collections.emptyList;
  47. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  48. import static org.assertj.core.api.Assertions.assertThat;
  49. import static org.mockito.ArgumentMatchers.eq;
  50. import static org.mockito.Mockito.mock;
  51. import static org.mockito.Mockito.reset;
  52. import static org.mockito.Mockito.verify;
  53. import static org.mockito.Mockito.verifyNoMoreInteractions;
  54. import static org.mockito.Mockito.verifyZeroInteractions;
  55. import static org.mockito.Mockito.when;
  56. import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
  57. import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.ERROR;
  58. import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.OK;
  59. public class QualityGateEventsStepTest {
  60. private static final String PROJECT_VERSION = randomAlphabetic(19);
  61. private static final ReportComponent PROJECT_COMPONENT = ReportComponent.builder(Component.Type.PROJECT, 1)
  62. .setUuid("uuid 1")
  63. .setKey("key 1")
  64. .setProjectVersion(PROJECT_VERSION)
  65. .setBuildString("V1.9")
  66. .addChildren(ReportComponent.builder(Component.Type.DIRECTORY, 2).build())
  67. .build();
  68. private static final String INVALID_ALERT_STATUS = "trololo";
  69. private static final String ALERT_TEXT = "alert text";
  70. private static final QualityGateStatus OK_QUALITY_GATE_STATUS = new QualityGateStatus(OK, ALERT_TEXT);
  71. private static final QualityGateStatus ERROR_QUALITY_GATE_STATUS = new QualityGateStatus(ERROR, ALERT_TEXT);
  72. @Rule
  73. public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
  74. @Rule
  75. public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
  76. private ArgumentCaptor<Event> eventArgumentCaptor = ArgumentCaptor.forClass(Event.class);
  77. private ArgumentCaptor<Notification> notificationArgumentCaptor = ArgumentCaptor.forClass(Notification.class);
  78. private Metric alertStatusMetric = mock(Metric.class);
  79. private MetricRepository metricRepository = mock(MetricRepository.class);
  80. private MeasureRepository measureRepository = mock(MeasureRepository.class);
  81. private EventRepository eventRepository = mock(EventRepository.class);
  82. private NotificationService notificationService = mock(NotificationService.class);
  83. private QualityGateEventsStep underTest = new QualityGateEventsStep(treeRootHolder, metricRepository, measureRepository, eventRepository, notificationService,
  84. analysisMetadataHolder);
  85. @Before
  86. public void setUp() {
  87. when(metricRepository.getByKey(ALERT_STATUS_KEY)).thenReturn(alertStatusMetric);
  88. analysisMetadataHolder
  89. .setProject(new Project(PROJECT_COMPONENT.getUuid(), PROJECT_COMPONENT.getDbKey(), PROJECT_COMPONENT.getName(), PROJECT_COMPONENT.getDescription(), emptyList()));
  90. analysisMetadataHolder.setBranch(mock(Branch.class));
  91. treeRootHolder.setRoot(PROJECT_COMPONENT);
  92. }
  93. @Test
  94. public void no_event_if_no_raw_ALERT_STATUS_measure() {
  95. when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(Optional.empty());
  96. underTest.execute(new TestComputationStepContext());
  97. verify(measureRepository).getRawMeasure(PROJECT_COMPONENT, alertStatusMetric);
  98. verifyNoMoreInteractions(measureRepository, eventRepository);
  99. }
  100. @Test
  101. public void no_event_created_if_raw_ALERT_STATUS_measure_is_null() {
  102. when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(of(Measure.newMeasureBuilder().createNoValue()));
  103. underTest.execute(new TestComputationStepContext());
  104. verify(measureRepository).getRawMeasure(PROJECT_COMPONENT, alertStatusMetric);
  105. verifyNoMoreInteractions(measureRepository, eventRepository);
  106. }
  107. private static Optional<Measure> of(Measure measure) {
  108. return Optional.of(measure);
  109. }
  110. @Test
  111. public void no_event_created_if_raw_ALERT_STATUS_measure_is_unsupported_value() {
  112. when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(of(Measure.newMeasureBuilder().create(INVALID_ALERT_STATUS)));
  113. underTest.execute(new TestComputationStepContext());
  114. verify(measureRepository).getRawMeasure(PROJECT_COMPONENT, alertStatusMetric);
  115. verifyNoMoreInteractions(measureRepository, eventRepository);
  116. }
  117. @Test
  118. public void no_event_created_if_no_base_ALERT_STATUS_and_raw_is_OK() {
  119. QualityGateStatus someQGStatus = new QualityGateStatus(Measure.Level.OK);
  120. when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(someQGStatus).createNoValue()));
  121. when(measureRepository.getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(of(Measure.newMeasureBuilder().createNoValue()));
  122. underTest.execute(new TestComputationStepContext());
  123. verify(measureRepository).getRawMeasure(PROJECT_COMPONENT, alertStatusMetric);
  124. verify(measureRepository).getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric);
  125. verifyNoMoreInteractions(measureRepository, eventRepository);
  126. }
  127. @Test
  128. public void event_created_if_base_ALERT_STATUS_has_no_alertStatus_and_raw_is_ERROR() {
  129. verify_event_created_if_no_base_ALERT_STATUS_measure(ERROR, "Red");
  130. }
  131. @Test
  132. public void event_created_if_base_ALERT_STATUS_has_invalid_alertStatus_and_raw_is_ERROR() {
  133. verify_event_created_if_no_base_ALERT_STATUS_measure(ERROR, "Red");
  134. }
  135. private void verify_event_created_if_no_base_ALERT_STATUS_measure(Measure.Level rawAlterStatus, String expectedLabel) {
  136. QualityGateStatus someQGStatus = new QualityGateStatus(rawAlterStatus, ALERT_TEXT);
  137. when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(someQGStatus).createNoValue()));
  138. when(measureRepository.getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(of(Measure.newMeasureBuilder().createNoValue()));
  139. underTest.execute(new TestComputationStepContext());
  140. verify(measureRepository).getRawMeasure(PROJECT_COMPONENT, alertStatusMetric);
  141. verify(measureRepository).getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric);
  142. verify(eventRepository).add(eq(PROJECT_COMPONENT), eventArgumentCaptor.capture());
  143. verifyNoMoreInteractions(measureRepository, eventRepository);
  144. Event event = eventArgumentCaptor.getValue();
  145. assertThat(event.getCategory()).isEqualTo(Event.Category.ALERT);
  146. assertThat(event.getName()).isEqualTo(expectedLabel);
  147. assertThat(event.getDescription()).isEqualTo(ALERT_TEXT);
  148. assertThat(event.getData()).isNull();
  149. verify(notificationService).deliver(notificationArgumentCaptor.capture());
  150. Notification notification = notificationArgumentCaptor.getValue();
  151. assertThat(notification.getType()).isEqualTo("alerts");
  152. assertThat(notification.getFieldValue("projectKey")).isEqualTo(PROJECT_COMPONENT.getKey());
  153. assertThat(notification.getFieldValue("projectName")).isEqualTo(PROJECT_COMPONENT.getName());
  154. assertThat(notification.getFieldValue("projectVersion")).isEqualTo(PROJECT_COMPONENT.getProjectAttributes().getProjectVersion());
  155. assertThat(notification.getFieldValue("branch")).isNull();
  156. assertThat(notification.getFieldValue("alertLevel")).isEqualTo(rawAlterStatus.name());
  157. assertThat(notification.getFieldValue("alertName")).isEqualTo(expectedLabel);
  158. }
  159. @Test
  160. public void no_event_created_if_base_ALERT_STATUS_measure_but_status_is_the_same() {
  161. when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric))
  162. .thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(OK_QUALITY_GATE_STATUS).createNoValue()));
  163. when(measureRepository.getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric))
  164. .thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(OK_QUALITY_GATE_STATUS).createNoValue()));
  165. underTest.execute(new TestComputationStepContext());
  166. verify(measureRepository).getRawMeasure(PROJECT_COMPONENT, alertStatusMetric);
  167. verify(measureRepository).getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric);
  168. verifyNoMoreInteractions(measureRepository, eventRepository);
  169. }
  170. @Test
  171. public void event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed() {
  172. verify_event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed(OK, ERROR_QUALITY_GATE_STATUS, "Red (was Green)");
  173. verify_event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed(ERROR, OK_QUALITY_GATE_STATUS, "Green (was Red)");
  174. }
  175. private void verify_event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed(Measure.Level previousAlertStatus,
  176. QualityGateStatus newQualityGateStatus, String expectedLabel) {
  177. when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric))
  178. .thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(newQualityGateStatus).createNoValue()));
  179. when(measureRepository.getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(
  180. of(Measure.newMeasureBuilder().setQualityGateStatus(new QualityGateStatus(previousAlertStatus)).createNoValue()));
  181. underTest.execute(new TestComputationStepContext());
  182. verify(measureRepository).getRawMeasure(PROJECT_COMPONENT, alertStatusMetric);
  183. verify(measureRepository).getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric);
  184. verify(eventRepository).add(eq(PROJECT_COMPONENT), eventArgumentCaptor.capture());
  185. verifyNoMoreInteractions(measureRepository, eventRepository);
  186. Event event = eventArgumentCaptor.getValue();
  187. assertThat(event.getCategory()).isEqualTo(Event.Category.ALERT);
  188. assertThat(event.getName()).isEqualTo(expectedLabel);
  189. assertThat(event.getDescription()).isEqualTo(ALERT_TEXT);
  190. assertThat(event.getData()).isNull();
  191. verify(notificationService).deliver(notificationArgumentCaptor.capture());
  192. Notification notification = notificationArgumentCaptor.getValue();
  193. assertThat(notification.getType()).isEqualTo("alerts");
  194. assertThat(notification.getFieldValue("projectKey")).isEqualTo(PROJECT_COMPONENT.getKey());
  195. assertThat(notification.getFieldValue("projectName")).isEqualTo(PROJECT_COMPONENT.getName());
  196. assertThat(notification.getFieldValue("projectVersion")).isEqualTo(PROJECT_COMPONENT.getProjectAttributes().getProjectVersion());
  197. assertThat(notification.getFieldValue("branch")).isNull();
  198. assertThat(notification.getFieldValue("alertLevel")).isEqualTo(newQualityGateStatus.getStatus().name());
  199. assertThat(notification.getFieldValue("alertName")).isEqualTo(expectedLabel);
  200. reset(measureRepository, eventRepository, notificationService);
  201. }
  202. @Test
  203. public void verify_branch_name_is_set_in_notification_when_not_main() {
  204. String branchName = "feature1";
  205. analysisMetadataHolder.setBranch(new DefaultBranchImpl(branchName) {
  206. @Override
  207. public boolean isMain() {
  208. return false;
  209. }
  210. });
  211. when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric))
  212. .thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(OK_QUALITY_GATE_STATUS).createNoValue()));
  213. when(measureRepository.getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(
  214. of(Measure.newMeasureBuilder().setQualityGateStatus(new QualityGateStatus(ERROR)).createNoValue()));
  215. underTest.execute(new TestComputationStepContext());
  216. verify(notificationService).deliver(notificationArgumentCaptor.capture());
  217. Notification notification = notificationArgumentCaptor.getValue();
  218. assertThat(notification.getType()).isEqualTo("alerts");
  219. assertThat(notification.getFieldValue("projectKey")).isEqualTo(PROJECT_COMPONENT.getKey());
  220. assertThat(notification.getFieldValue("projectName")).isEqualTo(PROJECT_COMPONENT.getName());
  221. assertThat(notification.getFieldValue("projectVersion")).isEqualTo(PROJECT_COMPONENT.getProjectAttributes().getProjectVersion());
  222. assertThat(notification.getFieldValue("branch")).isEqualTo(branchName);
  223. reset(measureRepository, eventRepository, notificationService);
  224. }
  225. @Test
  226. public void verify_branch_name_is_not_set_in_notification_when_main() {
  227. analysisMetadataHolder.setBranch(new DefaultBranchImpl());
  228. when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric))
  229. .thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(OK_QUALITY_GATE_STATUS).createNoValue()));
  230. when(measureRepository.getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(
  231. of(Measure.newMeasureBuilder().setQualityGateStatus(new QualityGateStatus(ERROR)).createNoValue()));
  232. underTest.execute(new TestComputationStepContext());
  233. verify(notificationService).deliver(notificationArgumentCaptor.capture());
  234. Notification notification = notificationArgumentCaptor.getValue();
  235. assertThat(notification.getType()).isEqualTo("alerts");
  236. assertThat(notification.getFieldValue("projectKey")).isEqualTo(PROJECT_COMPONENT.getKey());
  237. assertThat(notification.getFieldValue("projectName")).isEqualTo(PROJECT_COMPONENT.getName());
  238. assertThat(notification.getFieldValue("projectVersion")).isEqualTo(PROJECT_COMPONENT.getProjectAttributes().getProjectVersion());
  239. assertThat(notification.getFieldValue("branch")).isEqualTo(null);
  240. reset(measureRepository, eventRepository, notificationService);
  241. }
  242. @Test
  243. public void no_alert_on_short_living_branches() {
  244. Branch shortBranch = mock(Branch.class);
  245. when(shortBranch.getType()).thenReturn(BranchType.SHORT);
  246. analysisMetadataHolder.setBranch(shortBranch);
  247. TreeRootHolder treeRootHolder = mock(TreeRootHolder.class);
  248. MetricRepository metricRepository = mock(MetricRepository.class);
  249. MeasureRepository measureRepository = mock(MeasureRepository.class);
  250. EventRepository eventRepository = mock(EventRepository.class);
  251. NotificationService notificationService = mock(NotificationService.class);
  252. QualityGateEventsStep underTest = new QualityGateEventsStep(treeRootHolder, metricRepository, measureRepository,
  253. eventRepository, notificationService, analysisMetadataHolder);
  254. underTest.execute(new TestComputationStepContext());
  255. verifyZeroInteractions(treeRootHolder, metricRepository, measureRepository, eventRepository, notificationService);
  256. }
  257. @Test
  258. public void no_alert_on_pull_request_branches() {
  259. Branch shortBranch = mock(Branch.class);
  260. when(shortBranch.getType()).thenReturn(BranchType.PULL_REQUEST);
  261. analysisMetadataHolder.setBranch(shortBranch);
  262. TreeRootHolder treeRootHolder = mock(TreeRootHolder.class);
  263. MetricRepository metricRepository = mock(MetricRepository.class);
  264. MeasureRepository measureRepository = mock(MeasureRepository.class);
  265. EventRepository eventRepository = mock(EventRepository.class);
  266. NotificationService notificationService = mock(NotificationService.class);
  267. QualityGateEventsStep underTest = new QualityGateEventsStep(treeRootHolder, metricRepository, measureRepository,
  268. eventRepository, notificationService, analysisMetadataHolder);
  269. underTest.execute(new TestComputationStepContext());
  270. verifyZeroInteractions(treeRootHolder, metricRepository, measureRepository, eventRepository, notificationService);
  271. }
  272. }