]> source.dussan.org Git - sonarqube.git/blob
39af227174479cfe73a82e8d9f526f93c1b770bc
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2020 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.issue.index;
21
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Optional;
27 import org.junit.Before;
28 import org.junit.Rule;
29 import org.junit.Test;
30 import org.mockito.ArgumentCaptor;
31 import org.sonar.api.utils.System2;
32 import org.sonar.api.utils.log.LogTester;
33 import org.sonar.api.utils.log.LoggerLevel;
34 import org.sonar.ce.queue.CeQueue;
35 import org.sonar.ce.queue.CeTaskSubmit;
36 import org.sonar.core.util.SequenceUuidFactory;
37 import org.sonar.core.util.UuidFactory;
38 import org.sonar.db.DbClient;
39 import org.sonar.db.DbTester;
40 import org.sonar.db.ce.CeActivityDto;
41 import org.sonar.db.ce.CeActivityDto.Status;
42 import org.sonar.db.ce.CeQueueDto;
43 import org.sonar.db.ce.CeTaskCharacteristicDto;
44 import org.sonar.db.component.BranchDto;
45 import org.sonar.db.component.SnapshotDto;
46
47 import static org.assertj.core.api.Assertions.assertThat;
48 import static org.assertj.core.api.Assertions.tuple;
49 import static org.mockito.ArgumentMatchers.anyCollection;
50 import static org.mockito.Mockito.mock;
51 import static org.mockito.Mockito.times;
52 import static org.mockito.Mockito.verify;
53 import static org.mockito.Mockito.when;
54 import static org.sonar.db.ce.CeTaskCharacteristicDto.BRANCH_TYPE_KEY;
55 import static org.sonar.db.ce.CeTaskTypes.BRANCH_ISSUE_SYNC;
56 import static org.sonar.db.ce.CeTaskTypes.REPORT;
57 import static org.sonar.db.component.BranchType.BRANCH;
58 import static org.sonar.db.component.BranchType.PULL_REQUEST;
59 import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED;
60
61 public class AsyncIssueIndexingImplTest {
62
63   @Rule
64   public DbTester dbTester = DbTester.create(System2.INSTANCE);
65   @Rule
66   public LogTester logTester = new LogTester();
67
68   private DbClient dbClient = dbTester.getDbClient();
69   private CeQueue ceQueue = mock(CeQueue.class);
70   private UuidFactory uuidFactory = new SequenceUuidFactory();
71
72   private final AsyncIssueIndexingImpl underTest = new AsyncIssueIndexingImpl(ceQueue, dbClient);
73
74   @Before
75   public void before() {
76     when(ceQueue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(uuidFactory.create()));
77   }
78
79   @Test
80   public void triggerOnIndexCreation() {
81     BranchDto dto = new BranchDto()
82       .setBranchType(BRANCH)
83       .setKey("branchName")
84       .setUuid("branch_uuid")
85       .setProjectUuid("project_uuid");
86     dbClient.branchDao().insert(dbTester.getSession(), dto);
87     dbTester.commit();
88
89     underTest.triggerOnIndexCreation();
90
91     Optional<BranchDto> branch = dbClient.branchDao().selectByUuid(dbTester.getSession(), "branch_uuid");
92     assertThat(branch).isPresent();
93     assertThat(branch.get().isNeedIssueSync()).isTrue();
94     verify(ceQueue, times(1)).prepareSubmit();
95     verify(ceQueue, times(1)).massSubmit(anyCollection());
96     assertThat(logTester.logs(LoggerLevel.INFO))
97       .contains("1 branch found in need of issue sync : BranchDto{uuid='branch_uuid', projectUuid='project_uuid'," +
98         " kee='branchName', keyType=BRANCH, branchType=BRANCH, mergeBranchUuid='null', excludeFromPurge=false, needIssueSync=true}");
99   }
100
101   @Test
102   public void triggerOnIndexCreation_no_branch() {
103     underTest.triggerOnIndexCreation();
104
105     assertThat(logTester.logs(LoggerLevel.INFO)).contains("No branch found in need of issue sync");
106   }
107
108   @Test
109   public void remove_existing_indexation_task() {
110     CeQueueDto reportTask = new CeQueueDto();
111     reportTask.setUuid("uuid_1");
112     reportTask.setTaskType(REPORT);
113     dbClient.ceQueueDao().insert(dbTester.getSession(), reportTask);
114
115     CeActivityDto reportActivity = new CeActivityDto(reportTask);
116     reportActivity.setStatus(Status.SUCCESS);
117     dbClient.ceActivityDao().insert(dbTester.getSession(), reportActivity);
118     CeQueueDto task = new CeQueueDto();
119     task.setUuid("uuid_2");
120     task.setTaskType(BRANCH_ISSUE_SYNC);
121     dbClient.ceQueueDao().insert(dbTester.getSession(), task);
122
123     CeActivityDto activityDto = new CeActivityDto(task);
124     activityDto.setStatus(Status.SUCCESS);
125     dbClient.ceActivityDao().insert(dbTester.getSession(), activityDto);
126
127     dbTester.commit();
128
129     underTest.triggerOnIndexCreation();
130
131     assertThat(dbClient.ceQueueDao().selectAllInAscOrder(dbTester.getSession())).extracting("uuid")
132       .containsExactly(reportTask.getUuid());
133     assertThat(dbClient.ceActivityDao().selectByTaskType(dbTester.getSession(), BRANCH_ISSUE_SYNC)).isEmpty();
134
135     assertThat(dbClient.ceActivityDao().selectByTaskType(dbTester.getSession(), REPORT)).hasSize(1);
136
137     assertThat(dbClient.ceTaskCharacteristicsDao().selectByTaskUuids(dbTester.getSession(), new HashSet<>(Arrays.asList("uuid_2")))).hasSize(0);
138
139     assertThat(logTester.logs(LoggerLevel.INFO))
140       .contains(
141         "1 pending indexation task found to be deleted...",
142         "1 completed indexation task found to be deleted...",
143         "Indexation task deletion complete.",
144         "Deleting tasks characteristics...",
145         "Tasks characteristics deletion complete.");
146   }
147
148   @Test
149   public void order_by_last_analysis_date() {
150     BranchDto dto = new BranchDto()
151       .setBranchType(BRANCH)
152       .setKey("branch_1")
153       .setUuid("branch_uuid1")
154       .setProjectUuid("project_uuid1");
155     dbClient.branchDao().insert(dbTester.getSession(), dto);
156     dbTester.commit();
157     insertSnapshot("analysis_1", "project_uuid1", 1);
158
159     BranchDto dto2 = new BranchDto()
160       .setBranchType(BRANCH)
161       .setKey("branch_2")
162       .setUuid("branch_uuid2")
163       .setProjectUuid("project_uuid2");
164     dbClient.branchDao().insert(dbTester.getSession(), dto2);
165     dbTester.commit();
166     insertSnapshot("analysis_2", "project_uuid2", 2);
167
168     underTest.triggerOnIndexCreation();
169
170     verify(ceQueue, times(2)).prepareSubmit();
171
172     ArgumentCaptor<Collection<CeTaskSubmit>> captor = ArgumentCaptor.forClass(Collection.class);
173
174     verify(ceQueue, times(1)).massSubmit(captor.capture());
175     List<Collection<CeTaskSubmit>> captures = captor.getAllValues();
176     assertThat(captures).hasSize(1);
177     Collection<CeTaskSubmit> tasks = captures.get(0);
178     assertThat(tasks).hasSize(2);
179     assertThat(tasks)
180       .extracting(p -> p.getComponent().get().getUuid())
181       .containsExactly("branch_uuid2", "branch_uuid1");
182
183     assertThat(logTester.logs(LoggerLevel.INFO))
184       .contains("2 projects found in need of issue sync.");
185   }
186
187   @Test
188   public void characteristics_are_defined() {
189     BranchDto dto = new BranchDto()
190       .setBranchType(BRANCH)
191       .setKey("branch_1")
192       .setUuid("branch_uuid1")
193       .setProjectUuid("project_uuid1");
194     dbClient.branchDao().insert(dbTester.getSession(), dto);
195     dbTester.commit();
196     insertSnapshot("analysis_1", "project_uuid1", 1);
197
198     BranchDto dto2 = new BranchDto()
199       .setBranchType(PULL_REQUEST)
200       .setKey("pr_1")
201       .setUuid("pr_uuid_1")
202       .setProjectUuid("project_uuid2");
203     dbClient.branchDao().insert(dbTester.getSession(), dto2);
204     dbTester.commit();
205     insertSnapshot("analysis_2", "project_uuid2", 2);
206
207     underTest.triggerOnIndexCreation();
208
209     ArgumentCaptor<Collection<CeTaskSubmit>> captor = ArgumentCaptor.forClass(Collection.class);
210     verify(ceQueue, times(1)).massSubmit(captor.capture());
211     List<Collection<CeTaskSubmit>> captures = captor.getAllValues();
212     assertThat(captures).hasSize(1);
213     Collection<CeTaskSubmit> tasks = captures.get(0);
214     assertThat(tasks).hasSize(2);
215
216     assertThat(tasks)
217       .extracting(p -> p.getCharacteristics().get(BRANCH_TYPE_KEY),
218         p -> p.getCharacteristics().get(CeTaskCharacteristicDto.BRANCH_KEY),
219         p -> p.getCharacteristics().get(CeTaskCharacteristicDto.PULL_REQUEST))
220       .containsExactlyInAnyOrder(
221         tuple("BRANCH", "branch_1", null),
222         tuple("PULL_REQUEST", null, "pr_1"));
223   }
224
225   private SnapshotDto insertSnapshot(String analysisUuid, String projectUuid, long createdAt) {
226     SnapshotDto snapshot = new SnapshotDto()
227       .setUuid(analysisUuid)
228       .setComponentUuid(projectUuid)
229       .setStatus(STATUS_PROCESSED)
230       .setCreatedAt(createdAt)
231       .setLast(true);
232     dbTester.getDbClient().snapshotDao().insert(dbTester.getSession(), snapshot);
233     dbTester.commit();
234     return snapshot;
235   }
236
237 }