]> source.dussan.org Git - sonarqube.git/blob
21612c447341965790e2c9322d69376af11c8c81
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 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.component;
21
22 import java.util.List;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.sonar.api.resources.ResourceType;
26 import org.sonar.api.resources.ResourceTypes;
27 import org.sonar.api.utils.System2;
28 import org.sonar.db.DbClient;
29 import org.sonar.db.DbSession;
30 import org.sonar.db.DbTester;
31 import org.sonar.db.component.BranchDto;
32 import org.sonar.db.component.ComponentDto;
33 import org.sonar.db.component.ComponentTesting;
34 import org.sonar.db.component.SnapshotDto;
35 import org.sonar.db.issue.IssueDto;
36 import org.sonar.db.project.ProjectDto;
37 import org.sonar.db.rule.RuleDefinitionDto;
38 import org.sonar.db.webhook.WebhookDto;
39 import org.sonar.server.es.TestProjectIndexers;
40
41 import static java.util.Arrays.asList;
42 import static org.assertj.core.api.Assertions.assertThat;
43 import static org.assertj.core.api.Assertions.assertThatThrownBy;
44 import static org.mockito.ArgumentMatchers.anyString;
45 import static org.mockito.Mockito.mock;
46 import static org.mockito.Mockito.when;
47 import static org.sonar.db.component.ComponentTesting.newFileDto;
48 import static org.sonar.server.es.ProjectIndexer.Cause.PROJECT_DELETION;
49
50 public class ComponentCleanerServiceTest {
51
52   private final System2 system2 = System2.INSTANCE;
53
54   @Rule
55   public final DbTester db = DbTester.create(system2);
56
57   private final DbClient dbClient = db.getDbClient();
58   private final DbSession dbSession = db.getSession();
59   private final TestProjectIndexers projectIndexers = new TestProjectIndexers();
60   private final ResourceTypes mockResourceTypes = mock(ResourceTypes.class);
61   private final ComponentCleanerService underTest = new ComponentCleanerService(dbClient, mockResourceTypes, projectIndexers);
62
63   @Test
64   public void delete_project_from_db_and_index() {
65     DbData data1 = insertProjectData();
66     DbData data2 = insertProjectData();
67
68     underTest.delete(dbSession, data1.project);
69
70     assertNotExists(data1);
71     assertExists(data2);
72   }
73
74   @Test
75   public void delete_list_of_projects_from_db_and_index() {
76     DbData data1 = insertProjectData();
77     DbData data2 = insertProjectData();
78     DbData data3 = insertProjectData();
79
80     underTest.delete(dbSession, asList(data1.project, data2.project));
81     dbSession.commit();
82
83     assertNotExists(data1);
84     assertNotExists(data2);
85     assertExists(data3);
86   }
87
88   @Test
89   public void delete_list_of_components_from_db() {
90     ComponentDto componentDto1 = db.components().insertPublicProject();
91     ComponentDto componentDto2 = db.components().insertPublicProject();
92     ComponentDto componentDto3 = db.components().insertPublicProject();
93
94     mockResourceTypeAsValidProject();
95
96     underTest.deleteComponents(dbSession, asList(componentDto1, componentDto2));
97     dbSession.commit();
98
99     assertNotExists(componentDto1);
100     assertNotExists(componentDto2);
101     assertExists(componentDto3);
102   }
103
104   @Test
105   public void fail_with_IAE_if_project_non_deletable() {
106     ComponentDto componentDto1 = db.components().insertPublicProject();
107     ComponentDto componentDto2 = db.components().insertPublicProject();
108
109     mockResourceTypeAsNonDeletable();
110
111     dbSession.commit();
112
113     List<ComponentDto> componentDtos = asList(componentDto1, componentDto2);
114
115     assertThatThrownBy(() -> underTest.deleteComponents(dbSession, componentDtos))
116       .withFailMessage("Only projects can be deleted")
117       .isInstanceOf(IllegalArgumentException.class);
118   }
119
120   @Test
121   public void delete_application_from_db_and_index() {
122     DbData data1 = insertProjectData();
123     DbData data2 = insertProjectData();
124     DbData data3 = insertProjectData();
125     ProjectDto app1 = insertApplication(data2.project);
126     ProjectDto app2 = insertApplication(data3.project);
127
128     underTest.deleteApplication(dbSession, app1);
129     dbSession.commit();
130
131     assertProjectOrAppExists(app1, false);
132     assertProjectOrAppExists(app2, true);
133     assertExists(data1);
134     assertExists(data2);
135     assertExists(data3);
136   }
137
138   private ProjectDto insertApplication(ProjectDto project) {
139     ProjectDto app = db.components().insertPublicApplicationDto();
140     db.components().addApplicationProject(app, project);
141     return app;
142   }
143
144   @Test
145   public void delete_branch() {
146     DbData data1 = insertProjectData();
147     DbData data2 = insertProjectData();
148     DbData data3 = insertProjectData();
149
150     underTest.deleteBranch(dbSession, data1.branch);
151     dbSession.commit();
152
153     assertNotExists(data1);
154     assertExists(data2);
155     assertExists(data3);
156   }
157
158   @Test
159   public void delete_webhooks_from_projects() {
160     ProjectDto project1 = db.components().insertPrivateProjectDto();
161     WebhookDto webhook1 = db.webhooks().insertWebhook(project1);
162     db.webhookDelivery().insert(webhook1);
163     ProjectDto project2 = db.components().insertPrivateProjectDto();
164     WebhookDto webhook2 = db.webhooks().insertWebhook(project2);
165     db.webhookDelivery().insert(webhook2);
166     ProjectDto projectNotToBeDeleted = db.components().insertPrivateProjectDto();
167     WebhookDto webhook3 = db.webhooks().insertWebhook(projectNotToBeDeleted);
168     db.webhookDelivery().insert(webhook3);
169
170     ProjectDto projectDto1 = dbClient.projectDao().selectByUuid(dbSession, project1.getUuid()).get();
171     ProjectDto projectDto2 = dbClient.projectDao().selectByUuid(dbSession, project2.getUuid()).get();
172
173     mockResourceTypeAsValidProject();
174
175     underTest.delete(dbSession, asList(projectDto1, projectDto2));
176
177     assertThat(db.countRowsOfTable(db.getSession(), "webhooks")).isOne();
178     assertThat(db.countRowsOfTable(db.getSession(), "webhook_deliveries")).isOne();
179   }
180
181   @Test
182   public void fail_with_IAE_if_not_a_project() {
183     mockResourceTypeAsValidProject();
184     ComponentDto project = ComponentTesting.newPrivateProjectDto();
185     db.components().insertComponent(project);
186     ComponentDto file = newFileDto(project, null);
187     dbClient.componentDao().insert(dbSession, file);
188     dbSession.commit();
189
190     assertThatThrownBy(() -> underTest.delete(dbSession, file))
191       .isInstanceOf(IllegalArgumentException.class);
192   }
193
194   private DbData insertProjectData() {
195     ComponentDto componentDto = db.components().insertPublicProject();
196     ProjectDto project = dbClient.projectDao().selectByUuid(dbSession, componentDto.uuid()).get();
197     BranchDto branch = dbClient.branchDao().selectByUuid(dbSession, project.getUuid()).get();
198
199     RuleDefinitionDto rule = db.rules().insert();
200     IssueDto issue = db.issues().insert(rule, project, componentDto);
201     SnapshotDto analysis = db.components().insertSnapshot(componentDto);
202     mockResourceTypeAsValidProject();
203     return new DbData(project, branch, analysis, issue);
204   }
205
206   private void mockResourceTypeAsValidProject() {
207     ResourceType resourceType = mock(ResourceType.class);
208     when(resourceType.getBooleanProperty(anyString())).thenReturn(true);
209     when(mockResourceTypes.get(anyString())).thenReturn(resourceType);
210   }
211
212   private void mockResourceTypeAsNonDeletable() {
213     ResourceType resourceType = mock(ResourceType.class);
214     when(resourceType.getBooleanProperty("deletable")).thenReturn(false);
215     when(mockResourceTypes.get(anyString())).thenReturn(resourceType);
216   }
217
218   private void assertNotExists(DbData data) {
219     assertDataInDb(data, false);
220     assertThat(projectIndexers.hasBeenCalled(data.branch.getUuid(), PROJECT_DELETION)).isTrue();
221   }
222
223   private void assertExists(DbData data) {
224     assertDataInDb(data, true);
225     assertThat(projectIndexers.hasBeenCalled(data.branch.getUuid(), PROJECT_DELETION)).isFalse();
226   }
227
228   private void assertDataInDb(DbData data, boolean exists) {
229     assertProjectOrAppExists(data.project, exists);
230     assertThat(dbClient.snapshotDao().selectByUuid(dbSession, data.snapshot.getUuid()).isPresent()).isEqualTo(exists);
231     assertThat(dbClient.issueDao().selectByKey(dbSession, data.issue.getKey()).isPresent()).isEqualTo(exists);
232   }
233
234   private void assertProjectOrAppExists(ProjectDto appOrProject, boolean exists) {
235     assertThat(dbClient.projectDao().selectByUuid(dbSession, appOrProject.getUuid()).isPresent()).isEqualTo(exists);
236     assertThat(dbClient.componentDao().selectByUuid(dbSession, appOrProject.getUuid()).isPresent()).isEqualTo(exists);
237     assertThat(dbClient.branchDao().selectByUuid(dbSession, appOrProject.getUuid()).isPresent()).isEqualTo(exists);
238   }
239
240   private void assertNotExists(ComponentDto componentDto) {
241     assertComponentExists(componentDto, false);
242   }
243
244   private void assertExists(ComponentDto componentDto) {
245     assertComponentExists(componentDto, true);
246   }
247
248   private void assertComponentExists(ComponentDto componentDto, boolean exists) {
249     assertThat(dbClient.componentDao().selectByUuid(dbSession, componentDto.uuid()).isPresent()).isEqualTo(exists);
250   }
251   
252   private static class DbData {
253     final ProjectDto project;
254     final BranchDto branch;
255     final SnapshotDto snapshot;
256     final IssueDto issue;
257
258     DbData(ProjectDto project, BranchDto branch, SnapshotDto snapshot, IssueDto issue) {
259       this.project = project;
260       this.branch = branch;
261       this.snapshot = snapshot;
262       this.issue = issue;
263     }
264   }
265 }