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.

PurgeDaoTest.java 68KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379
  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.db.purge;
  21. import com.google.common.collect.ImmutableList;
  22. import com.google.common.collect.ImmutableSet;
  23. import java.io.ByteArrayInputStream;
  24. import java.util.Arrays;
  25. import java.util.Collections;
  26. import java.util.Date;
  27. import java.util.List;
  28. import java.util.Optional;
  29. import java.util.Random;
  30. import java.util.stream.Collectors;
  31. import java.util.stream.IntStream;
  32. import java.util.stream.Stream;
  33. import org.apache.commons.lang.math.RandomUtils;
  34. import org.apache.commons.lang.time.DateUtils;
  35. import org.junit.Rule;
  36. import org.junit.Test;
  37. import org.junit.rules.ExpectedException;
  38. import org.sonar.api.resources.Scopes;
  39. import org.sonar.api.utils.System2;
  40. import org.sonar.core.util.CloseableIterator;
  41. import org.sonar.core.util.UuidFactoryFast;
  42. import org.sonar.core.util.Uuids;
  43. import org.sonar.db.DbClient;
  44. import org.sonar.db.DbSession;
  45. import org.sonar.db.DbTester;
  46. import org.sonar.db.alm.ALM;
  47. import org.sonar.db.ce.CeActivityDto;
  48. import org.sonar.db.ce.CeQueueDto;
  49. import org.sonar.db.ce.CeQueueDto.Status;
  50. import org.sonar.db.ce.CeTaskCharacteristicDto;
  51. import org.sonar.db.ce.CeTaskMessageDto;
  52. import org.sonar.db.component.BranchDto;
  53. import org.sonar.db.component.BranchType;
  54. import org.sonar.db.component.ComponentDbTester;
  55. import org.sonar.db.component.ComponentDto;
  56. import org.sonar.db.component.ComponentTesting;
  57. import org.sonar.db.component.SnapshotDto;
  58. import org.sonar.db.event.EventComponentChangeDto;
  59. import org.sonar.db.event.EventDto;
  60. import org.sonar.db.event.EventTesting;
  61. import org.sonar.db.issue.IssueDto;
  62. import org.sonar.db.measure.LiveMeasureDto;
  63. import org.sonar.db.measure.MeasureDto;
  64. import org.sonar.db.measure.custom.CustomMeasureDto;
  65. import org.sonar.db.metric.MetricDto;
  66. import org.sonar.db.organization.OrganizationDto;
  67. import org.sonar.db.property.PropertyDto;
  68. import org.sonar.db.rule.RuleDefinitionDto;
  69. import org.sonar.db.source.FileSourceDto;
  70. import org.sonar.db.webhook.WebhookDeliveryLiteDto;
  71. import org.sonar.db.webhook.WebhookDto;
  72. import static com.google.common.base.MoreObjects.firstNonNull;
  73. import static java.util.Arrays.asList;
  74. import static java.util.Collections.emptyList;
  75. import static java.util.Collections.singletonList;
  76. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  77. import static org.assertj.core.api.Assertions.assertThat;
  78. import static org.mockito.Mockito.mock;
  79. import static org.mockito.Mockito.verifyZeroInteractions;
  80. import static org.mockito.Mockito.when;
  81. import static org.sonar.db.ce.CeTaskTypes.REPORT;
  82. import static org.sonar.db.component.ComponentTesting.newBranchDto;
  83. import static org.sonar.db.component.ComponentTesting.newDirectory;
  84. import static org.sonar.db.component.ComponentTesting.newFileDto;
  85. import static org.sonar.db.component.ComponentTesting.newModuleDto;
  86. import static org.sonar.db.component.ComponentTesting.newProjectCopy;
  87. import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED;
  88. import static org.sonar.db.component.SnapshotDto.STATUS_UNPROCESSED;
  89. import static org.sonar.db.component.SnapshotTesting.newSnapshot;
  90. import static org.sonar.db.event.EventDto.CATEGORY_VERSION;
  91. import static org.sonar.db.webhook.WebhookDeliveryTesting.newDto;
  92. import static org.sonar.db.webhook.WebhookDeliveryTesting.selectAllDeliveryUuids;
  93. public class PurgeDaoTest {
  94. private static final String PROJECT_UUID = "P1";
  95. private System2 system2 = mock(System2.class);
  96. @Rule
  97. public DbTester db = DbTester.create(system2);
  98. @Rule
  99. public ExpectedException expectedException = ExpectedException.none();
  100. private DbClient dbClient = db.getDbClient();
  101. private DbSession dbSession = db.getSession();
  102. private PurgeDao underTest = db.getDbClient().purgeDao();
  103. @Test
  104. public void purge_failed_ce_tasks() {
  105. db.prepareDbUnit(getClass(), "shouldDeleteAbortedBuilds.xml");
  106. underTest.purge(dbSession, newConfigurationWith30Days(), PurgeListener.EMPTY, new PurgeProfiler());
  107. dbSession.commit();
  108. db.assertDbUnit(getClass(), "shouldDeleteAbortedBuilds-result.xml", "snapshots");
  109. }
  110. @Test
  111. public void purge_history_of_project() {
  112. db.prepareDbUnit(getClass(), "shouldPurgeProject.xml");
  113. underTest.purge(dbSession, newConfigurationWith30Days(), PurgeListener.EMPTY, new PurgeProfiler());
  114. dbSession.commit();
  115. db.assertDbUnit(getClass(), "shouldPurgeProject-result.xml", "projects", "snapshots");
  116. }
  117. @Test
  118. public void purge_inactive_short_living_branches() {
  119. when(system2.now()).thenReturn(new Date().getTime());
  120. RuleDefinitionDto rule = db.rules().insert();
  121. ComponentDto project = db.components().insertMainBranch();
  122. ComponentDto longBranch = db.components().insertProjectBranch(project);
  123. ComponentDto recentShortBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.SHORT));
  124. // short branch with other components and issues, updated 31 days ago
  125. when(system2.now()).thenReturn(DateUtils.addDays(new Date(), -31).getTime());
  126. ComponentDto shortBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.SHORT));
  127. ComponentDto module = db.components().insertComponent(newModuleDto(shortBranch));
  128. ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
  129. ComponentDto file = db.components().insertComponent(newFileDto(subModule));
  130. db.issues().insert(rule, shortBranch, file);
  131. db.issues().insert(rule, shortBranch, subModule);
  132. db.issues().insert(rule, shortBranch, module);
  133. // back to present
  134. when(system2.now()).thenReturn(new Date().getTime());
  135. underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
  136. dbSession.commit();
  137. assertThat(uuidsIn("projects")).containsOnly(project.uuid(), longBranch.uuid(), recentShortBranch.uuid());
  138. }
  139. @Test
  140. public void purge_inactive_pull_request() {
  141. when(system2.now()).thenReturn(new Date().getTime());
  142. RuleDefinitionDto rule = db.rules().insert();
  143. ComponentDto project = db.components().insertMainBranch();
  144. ComponentDto longBranch = db.components().insertProjectBranch(project);
  145. ComponentDto recentPullRequest = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST));
  146. // pull request with other components and issues, updated 31 days ago
  147. when(system2.now()).thenReturn(DateUtils.addDays(new Date(), -31).getTime());
  148. ComponentDto pullRequest = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST));
  149. ComponentDto module = db.components().insertComponent(newModuleDto(pullRequest));
  150. ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
  151. ComponentDto file = db.components().insertComponent(newFileDto(subModule));
  152. db.issues().insert(rule, pullRequest, file);
  153. db.issues().insert(rule, pullRequest, subModule);
  154. db.issues().insert(rule, pullRequest, module);
  155. // back to present
  156. when(system2.now()).thenReturn(new Date().getTime());
  157. underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
  158. dbSession.commit();
  159. assertThat(uuidsIn("projects")).containsOnly(project.uuid(), longBranch.uuid(), recentPullRequest.uuid());
  160. }
  161. @Test
  162. public void purge_inactive_SLB_when_analyzing_non_main_branch() {
  163. when(system2.now()).thenReturn(new Date().getTime());
  164. RuleDefinitionDto rule = db.rules().insert();
  165. ComponentDto project = db.components().insertMainBranch();
  166. ComponentDto longBranch = db.components().insertProjectBranch(project);
  167. when(system2.now()).thenReturn(DateUtils.addDays(new Date(), -31).getTime());
  168. // SLB updated 31 days ago
  169. ComponentDto slb1 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.SHORT));
  170. // SLB with other components and issues, updated 31 days ago
  171. ComponentDto slb2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST));
  172. ComponentDto file = db.components().insertComponent(newFileDto(slb2));
  173. db.issues().insert(rule, slb2, file);
  174. // back to present
  175. when(system2.now()).thenReturn(new Date().getTime());
  176. // analysing slb1
  177. underTest.purge(dbSession, newConfigurationWith30Days(system2, slb1.uuid(), slb1.getMainBranchProjectUuid()), PurgeListener.EMPTY, new PurgeProfiler());
  178. dbSession.commit();
  179. // slb1 wasn't deleted since it was being analyzed!
  180. assertThat(uuidsIn("projects")).containsOnly(project.uuid(), longBranch.uuid(), slb1.uuid());
  181. }
  182. @Test
  183. public void shouldDeleteHistoricalDataOfDirectoriesAndFiles() {
  184. db.prepareDbUnit(getClass(), "shouldDeleteHistoricalDataOfDirectoriesAndFiles.xml");
  185. PurgeConfiguration conf = new PurgeConfiguration("PROJECT_UUID", "PROJECT_UUID", asList(Scopes.DIRECTORY, Scopes.FILE),
  186. 30, Optional.of(30), System2.INSTANCE, Collections.emptyList());
  187. underTest.purge(dbSession, conf, PurgeListener.EMPTY, new PurgeProfiler());
  188. dbSession.commit();
  189. db.assertDbUnit(getClass(), "shouldDeleteHistoricalDataOfDirectoriesAndFiles-result.xml", "projects", "snapshots", "project_measures");
  190. }
  191. @Test
  192. public void close_issues_clean_index_and_file_sources_of_disabled_components_specified_by_uuid_in_configuration() {
  193. // components and issues, updated 31 days ago
  194. when(system2.now()).thenReturn(DateUtils.addDays(new Date(), -31).getTime());
  195. RuleDefinitionDto rule = db.rules().insert();
  196. ComponentDto project = db.components().insertMainBranch(p -> p.setEnabled(false));
  197. db.components().insertSnapshot(project);
  198. db.components().insertSnapshot(project);
  199. db.components().insertSnapshot(project, s -> s.setLast(false));
  200. ComponentDto module = db.components().insertComponent(newModuleDto(project).setEnabled(false));
  201. ComponentDto dir = db.components().insertComponent(newDirectory(module, "sub").setEnabled(false));
  202. ComponentDto srcFile = db.components().insertComponent(newFileDto(module, dir).setEnabled(false));
  203. ComponentDto testFile = db.components().insertComponent(newFileDto(module, dir).setEnabled(false));
  204. ComponentDto nonSelectedFile = db.components().insertComponent(newFileDto(module, dir).setEnabled(false));
  205. IssueDto openOnFile = db.issues().insert(rule, project, srcFile, issue -> issue.setStatus("OPEN"));
  206. IssueDto confirmOnFile = db.issues().insert(rule, project, srcFile, issue -> issue.setStatus("CONFIRM"));
  207. IssueDto openOnDir = db.issues().insert(rule, project, dir, issue -> issue.setStatus("OPEN"));
  208. IssueDto confirmOnDir = db.issues().insert(rule, project, dir, issue -> issue.setStatus("CONFIRM"));
  209. IssueDto openOnNonSelected = db.issues().insert(rule, project, nonSelectedFile, issue -> issue.setStatus("OPEN"));
  210. IssueDto confirmOnNonSelected = db.issues().insert(rule, project, nonSelectedFile, issue -> issue.setStatus("CONFIRM"));
  211. assertThat(db.countSql("select count(*) from snapshots where purge_status = 1")).isEqualTo(0);
  212. assertThat(db.countSql("select count(*) from issues where status = 'CLOSED'")).isEqualTo(0);
  213. assertThat(db.countSql("select count(*) from issues where resolution = 'REMOVED'")).isEqualTo(0);
  214. db.fileSources().insertFileSource(srcFile);
  215. FileSourceDto nonSelectedFileSource = db.fileSources().insertFileSource(nonSelectedFile);
  216. assertThat(db.countRowsOfTable("file_sources")).isEqualTo(2);
  217. MetricDto metric1 = db.measures().insertMetric();
  218. MetricDto metric2 = db.measures().insertMetric();
  219. LiveMeasureDto liveMeasureMetric1OnFile = db.measures().insertLiveMeasure(srcFile, metric1);
  220. LiveMeasureDto liveMeasureMetric2OnFile = db.measures().insertLiveMeasure(srcFile, metric2);
  221. LiveMeasureDto liveMeasureMetric1OnDir = db.measures().insertLiveMeasure(dir, metric1);
  222. LiveMeasureDto liveMeasureMetric2OnDir = db.measures().insertLiveMeasure(dir, metric2);
  223. LiveMeasureDto liveMeasureMetric1OnProject = db.measures().insertLiveMeasure(project, metric1);
  224. LiveMeasureDto liveMeasureMetric2OnProject = db.measures().insertLiveMeasure(project, metric2);
  225. LiveMeasureDto liveMeasureMetric1OnNonSelected = db.measures().insertLiveMeasure(nonSelectedFile, metric1);
  226. LiveMeasureDto liveMeasureMetric2OnNonSelected = db.measures().insertLiveMeasure(nonSelectedFile, metric2);
  227. assertThat(db.countRowsOfTable("live_measures")).isEqualTo(8);
  228. // back to present
  229. when(system2.now()).thenReturn(new Date().getTime());
  230. underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid(), module.uuid(), dir.uuid(), srcFile.uuid(), testFile.uuid()), PurgeListener.EMPTY,
  231. new PurgeProfiler());
  232. dbSession.commit();
  233. // set purge_status=1 for non-last snapshot
  234. assertThat(db.countSql("select count(*) from snapshots where purge_status = 1")).isEqualTo(1);
  235. // close open issues of selected
  236. assertThat(db.countSql("select count(*) from issues where status = 'CLOSED'")).isEqualTo(4);
  237. for (IssueDto issue : Arrays.asList(openOnFile, confirmOnFile, openOnDir, confirmOnDir)) {
  238. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, issue.getKey()).get())
  239. .extracting("status", "resolution")
  240. .containsExactlyInAnyOrder("CLOSED", "REMOVED");
  241. }
  242. for (IssueDto issue : Arrays.asList(openOnNonSelected, confirmOnNonSelected)) {
  243. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, issue.getKey()).get())
  244. .extracting("status", "resolution")
  245. .containsExactlyInAnyOrder(issue.getStatus(), null);
  246. }
  247. // delete file sources of selected
  248. assertThat(db.countRowsOfTable("file_sources")).isEqualTo(1);
  249. assertThat(db.getDbClient().fileSourceDao().selectByFileUuid(dbSession, nonSelectedFileSource.getFileUuid())).isNotNull();
  250. // deletes live measure of selected
  251. assertThat(db.countRowsOfTable("live_measures")).isEqualTo(4);
  252. List<LiveMeasureDto> liveMeasureDtos = db.getDbClient().liveMeasureDao().selectByComponentUuidsAndMetricIds(dbSession,
  253. ImmutableSet.of(srcFile.uuid(), dir.uuid(), project.uuid(), nonSelectedFile.uuid()), ImmutableSet.of(metric1.getId(), metric2.getId()));
  254. assertThat(liveMeasureDtos)
  255. .extracting(LiveMeasureDto::getComponentUuid)
  256. .containsOnly(nonSelectedFile.uuid(), project.uuid());
  257. assertThat(liveMeasureDtos)
  258. .extracting(LiveMeasureDto::getMetricId)
  259. .containsOnly(metric1.getId(), metric2.getId());
  260. }
  261. @Test
  262. public void shouldDeleteAnalyses() {
  263. db.prepareDbUnit(getClass(), "shouldDeleteAnalyses.xml");
  264. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(new IdUuidPair(3, "u3")));
  265. db.assertDbUnit(getClass(), "shouldDeleteAnalyses-result.xml", "snapshots");
  266. }
  267. @Test
  268. public void deleteAnalyses_deletes_rows_in_events_and_event_component_changes() {
  269. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  270. dbClient.componentDao().insert(dbSession, project);
  271. SnapshotDto projectAnalysis1 = db.components().insertSnapshot(project);
  272. SnapshotDto projectAnalysis2 = db.components().insertSnapshot(project);
  273. SnapshotDto projectAnalysis3 = db.components().insertSnapshot(project);
  274. SnapshotDto projectAnalysis4 = db.components().insertSnapshot(project);
  275. EventDto projectEvent1 = db.events().insertEvent(projectAnalysis1);
  276. EventDto projectEvent2 = db.events().insertEvent(projectAnalysis2);
  277. EventDto projectEvent3 = db.events().insertEvent(projectAnalysis3);
  278. // note: projectAnalysis4 has no event
  279. ComponentDto referencedProjectA = db.components().insertPublicProject();
  280. ComponentDto referencedProjectB = db.components().insertPublicProject();
  281. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectA, null);
  282. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectB, null);
  283. BranchDto branchProjectA = newBranchDto(referencedProjectA);
  284. ComponentDto cptBranchProjectA = ComponentTesting.newProjectBranch(referencedProjectA, branchProjectA);
  285. db.events().insertEventComponentChanges(projectEvent2, projectAnalysis2, randomChangeCategory(), cptBranchProjectA, branchProjectA);
  286. // note: projectEvent3 has no component change
  287. // delete non existing analysis has no effect
  288. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(new IdUuidPair(3, "foo")));
  289. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  290. .containsOnly(projectAnalysis1.getUuid(), projectAnalysis2.getUuid());
  291. assertThat(db.countRowsOfTable("event_component_changes"))
  292. .isEqualTo(3);
  293. assertThat(uuidsIn("events"))
  294. .containsOnly(projectEvent1.getUuid(), projectEvent2.getUuid(), projectEvent3.getUuid());
  295. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(new IdUuidPair(projectAnalysis1.getId(), projectAnalysis1.getUuid())));
  296. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  297. .containsOnly(projectAnalysis2.getUuid());
  298. assertThat(db.countRowsOfTable("event_component_changes"))
  299. .isEqualTo(1);
  300. assertThat(uuidsIn("events"))
  301. .containsOnly(projectEvent2.getUuid(), projectEvent3.getUuid());
  302. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(new IdUuidPair(projectAnalysis4.getId(), projectAnalysis4.getUuid())));
  303. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  304. .containsOnly(projectAnalysis2.getUuid());
  305. assertThat(db.countRowsOfTable("event_component_changes"))
  306. .isEqualTo(1);
  307. assertThat(uuidsIn("events"))
  308. .containsOnly(projectEvent2.getUuid(), projectEvent3.getUuid());
  309. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(new IdUuidPair(projectAnalysis3.getId(), projectAnalysis3.getUuid())));
  310. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  311. .containsOnly(projectAnalysis2.getUuid());
  312. assertThat(db.countRowsOfTable("event_component_changes"))
  313. .isEqualTo(1);
  314. assertThat(uuidsIn("events"))
  315. .containsOnly(projectEvent2.getUuid());
  316. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(new IdUuidPair(projectAnalysis2.getId(), projectAnalysis2.getUuid())));
  317. assertThat(db.countRowsOfTable("event_component_changes"))
  318. .isZero();
  319. assertThat(db.countRowsOfTable("events"))
  320. .isZero();
  321. }
  322. @Test
  323. public void selectPurgeableAnalyses() {
  324. SnapshotDto[] analyses = new SnapshotDto[] {
  325. newSnapshot()
  326. .setUuid("u1")
  327. .setComponentUuid(PROJECT_UUID)
  328. .setStatus(STATUS_PROCESSED)
  329. .setLast(true),
  330. // not processed -> exclude
  331. newSnapshot()
  332. .setUuid("u2")
  333. .setComponentUuid(PROJECT_UUID)
  334. .setStatus(STATUS_UNPROCESSED)
  335. .setLast(false),
  336. // on other resource -> exclude
  337. newSnapshot()
  338. .setUuid("u3")
  339. .setComponentUuid("uuid_222")
  340. .setStatus(STATUS_PROCESSED)
  341. .setLast(true),
  342. // without event -> select
  343. newSnapshot()
  344. .setUuid("u4")
  345. .setComponentUuid(PROJECT_UUID)
  346. .setStatus(STATUS_PROCESSED)
  347. .setLast(false),
  348. // with event -> select
  349. newSnapshot()
  350. .setUuid("u5")
  351. .setComponentUuid(PROJECT_UUID)
  352. .setStatus(STATUS_PROCESSED)
  353. .setLast(false)
  354. .setProjectVersion("V5")
  355. };
  356. db.components().insertSnapshots(analyses);
  357. db.events().insertEvent(EventTesting.newEvent(analyses[4])
  358. .setName("V5")
  359. .setCategory(CATEGORY_VERSION));
  360. List<PurgeableAnalysisDto> purgeableAnalyses = underTest.selectPurgeableAnalyses(PROJECT_UUID, dbSession);
  361. assertThat(purgeableAnalyses).hasSize(3);
  362. assertThat(getById(purgeableAnalyses, "u1").isLast()).isTrue();
  363. assertThat(getById(purgeableAnalyses, "u1").hasEvents()).isFalse();
  364. assertThat(getById(purgeableAnalyses, "u1").getVersion()).isNull();
  365. assertThat(getById(purgeableAnalyses, "u4").isLast()).isFalse();
  366. assertThat(getById(purgeableAnalyses, "u4").hasEvents()).isFalse();
  367. assertThat(getById(purgeableAnalyses, "u4").getVersion()).isNull();
  368. assertThat(getById(purgeableAnalyses, "u5").isLast()).isFalse();
  369. assertThat(getById(purgeableAnalyses, "u5").hasEvents()).isTrue();
  370. assertThat(getById(purgeableAnalyses, "u5").getVersion()).isEqualTo("V5");
  371. }
  372. @Test
  373. public void selectPurgeableAnalyses_does_not_return_the_baseline() {
  374. ComponentDto project1 = db.components().insertMainBranch(db.getDefaultOrganization(), "master");
  375. SnapshotDto analysis1 = db.components().insertSnapshot(newSnapshot()
  376. .setComponentUuid(project1.uuid())
  377. .setStatus(STATUS_PROCESSED)
  378. .setLast(false));
  379. dbClient.branchDao().updateManualBaseline(dbSession, project1.uuid(), analysis1.getUuid());
  380. ComponentDto project2 = db.components().insertPrivateProject();
  381. SnapshotDto analysis2 = db.components().insertSnapshot(newSnapshot()
  382. .setComponentUuid(project2.uuid())
  383. .setStatus(STATUS_PROCESSED)
  384. .setLast(false));
  385. db.components().insertProjectBranch(project2);
  386. assertThat(underTest.selectPurgeableAnalyses(project1.uuid(), dbSession)).isEmpty();
  387. assertThat(underTest.selectPurgeableAnalyses(project2.uuid(), dbSession))
  388. .extracting(PurgeableAnalysisDto::getAnalysisUuid)
  389. .containsOnly(analysis2.getUuid());
  390. }
  391. @Test
  392. public void selectPurgeableAnalyses_does_not_return_the_baseline_of_specific_branch() {
  393. ComponentDto project = db.components().insertMainBranch(db.getDefaultOrganization(), "master");
  394. SnapshotDto analysisProject = db.components().insertSnapshot(newSnapshot()
  395. .setComponentUuid(project.uuid())
  396. .setStatus(STATUS_PROCESSED)
  397. .setLast(false));
  398. dbClient.branchDao().updateManualBaseline(dbSession, project.uuid(), analysisProject.getUuid());
  399. ComponentDto branch1 = db.components().insertProjectBranch(project);
  400. SnapshotDto analysisBranch1 = db.components().insertSnapshot(newSnapshot()
  401. .setComponentUuid(branch1.uuid())
  402. .setStatus(STATUS_PROCESSED)
  403. .setLast(false));
  404. ComponentDto branch2 = db.components().insertProjectBranch(project);
  405. SnapshotDto analysisBranch2 = db.components().insertSnapshot(newSnapshot()
  406. .setComponentUuid(branch2.uuid())
  407. .setStatus(STATUS_PROCESSED)
  408. .setLast(false));
  409. dbClient.branchDao().updateManualBaseline(dbSession, branch2.uuid(), analysisBranch2.getUuid());
  410. dbSession.commit();
  411. assertThat(underTest.selectPurgeableAnalyses(project.uuid(), dbSession))
  412. .isEmpty();
  413. assertThat(underTest.selectPurgeableAnalyses(branch1.uuid(), dbSession))
  414. .extracting(PurgeableAnalysisDto::getAnalysisUuid)
  415. .containsOnly(analysisBranch1.getUuid());
  416. assertThat(underTest.selectPurgeableAnalyses(branch2.uuid(), dbSession))
  417. .isEmpty();
  418. }
  419. @Test
  420. public void delete_project_and_associated_data() {
  421. db.prepareDbUnit(getClass(), "shouldDeleteProject.xml");
  422. underTest.deleteProject(dbSession, "A");
  423. dbSession.commit();
  424. assertThat(db.countRowsOfTable("projects")).isZero();
  425. assertThat(db.countRowsOfTable("snapshots")).isZero();
  426. assertThat(db.countRowsOfTable("issues")).isZero();
  427. assertThat(db.countRowsOfTable("issue_changes")).isZero();
  428. assertThat(db.countRowsOfTable("file_sources")).isZero();
  429. }
  430. @Test
  431. public void delete_webhooks_from_project() {
  432. OrganizationDto organization = db.organizations().insert();
  433. ComponentDto project1 = db.components().insertPrivateProject(organization);
  434. WebhookDto webhook = db.webhooks().insertWebhook(project1);
  435. db.webhookDelivery().insert(webhook);
  436. ComponentDto projectNotToBeDeleted = db.components().insertPrivateProject(organization);
  437. WebhookDto webhookNotDeleted = db.webhooks().insertWebhook(projectNotToBeDeleted);
  438. WebhookDeliveryLiteDto webhookDeliveryNotDeleted = db.webhookDelivery().insert(webhookNotDeleted);
  439. underTest.deleteProject(dbSession, project1.uuid());
  440. assertThat(db.select(db.getSession(), "select uuid as \"uuid\" from webhooks"))
  441. .extracting(m -> m.get("uuid"))
  442. .containsExactlyInAnyOrder(webhookNotDeleted.getUuid());
  443. assertThat(db.select(db.getSession(), "select uuid as \"uuid\" from webhook_deliveries"))
  444. .extracting(m -> m.get("uuid"))
  445. .containsExactlyInAnyOrder(webhookDeliveryNotDeleted.getUuid());
  446. }
  447. private Stream<String> uuidsOfTable(String tableName) {
  448. return db.select("select uuid as \"UUID\" from " + tableName)
  449. .stream()
  450. .map(s -> (String) s.get("UUID"));
  451. }
  452. @Test
  453. public void delete_row_in_ce_activity_when_deleting_project() {
  454. ComponentDto projectToBeDeleted = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  455. ComponentDto anotherLivingProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  456. dbClient.componentDao().insert(dbSession, projectToBeDeleted, anotherLivingProject);
  457. // Insert 2 rows in CE_ACTIVITY : one for the project that will be deleted, and one on another project
  458. CeActivityDto toBeDeletedActivity = insertCeActivity(projectToBeDeleted);
  459. CeActivityDto notDeletedActivity = insertCeActivity(anotherLivingProject);
  460. dbSession.commit();
  461. underTest.deleteProject(dbSession, projectToBeDeleted.uuid());
  462. dbSession.commit();
  463. assertThat(uuidsOfTable("ce_activity"))
  464. .containsOnly(notDeletedActivity.getUuid())
  465. .hasSize(1);
  466. }
  467. @Test
  468. public void delete_row_in_ce_task_input_referring_to_a_row_in_ce_activity_when_deleting_project() {
  469. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  470. ComponentDto branch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  471. ComponentDto anotherBranch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  472. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  473. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  474. CeActivityDto projectTask = insertCeActivity(project);
  475. insertCeTaskInput(projectTask.getUuid());
  476. CeActivityDto branchTask = insertCeActivity(branch);
  477. insertCeTaskInput(branchTask.getUuid());
  478. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch);
  479. insertCeTaskInput(anotherBranchTask.getUuid());
  480. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject);
  481. insertCeTaskInput(anotherProjectTask.getUuid());
  482. insertCeTaskInput("non existing task");
  483. dbSession.commit();
  484. underTest.deleteProject(dbSession, branch.uuid());
  485. dbSession.commit();
  486. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  487. assertThat(taskUuidsIn("ce_task_input")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  488. underTest.deleteProject(dbSession, project.uuid());
  489. dbSession.commit();
  490. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  491. assertThat(taskUuidsIn("ce_task_input")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  492. }
  493. @Test
  494. public void delete_row_in_ce_scanner_context_referring_to_a_row_in_ce_activity_when_deleting_project() {
  495. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  496. ComponentDto branch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  497. ComponentDto anotherBranch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  498. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  499. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  500. CeActivityDto projectTask = insertCeActivity(project);
  501. insertCeScannerContext(projectTask.getUuid());
  502. CeActivityDto branchTask = insertCeActivity(branch);
  503. insertCeScannerContext(branchTask.getUuid());
  504. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch);
  505. insertCeScannerContext(anotherBranchTask.getUuid());
  506. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject);
  507. insertCeScannerContext(anotherProjectTask.getUuid());
  508. insertCeScannerContext("non existing task");
  509. dbSession.commit();
  510. underTest.deleteProject(dbSession, branch.uuid());
  511. dbSession.commit();
  512. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  513. assertThat(taskUuidsIn("ce_scanner_context")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  514. underTest.deleteProject(dbSession, project.uuid());
  515. dbSession.commit();
  516. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  517. assertThat(taskUuidsIn("ce_scanner_context")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  518. }
  519. @Test
  520. public void delete_row_in_ce_task_characteristics_referring_to_a_row_in_ce_activity_when_deleting_project() {
  521. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  522. ComponentDto branch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  523. ComponentDto anotherBranch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  524. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  525. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  526. CeActivityDto projectTask = insertCeActivity(project);
  527. insertCeTaskCharacteristics(projectTask.getUuid(), 3);
  528. CeActivityDto branchTask = insertCeActivity(branch);
  529. insertCeTaskCharacteristics(branchTask.getUuid(), 2);
  530. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch);
  531. insertCeTaskCharacteristics(anotherBranchTask.getUuid(), 6);
  532. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject);
  533. insertCeTaskCharacteristics(anotherProjectTask.getUuid(), 2);
  534. insertCeTaskCharacteristics("non existing task", 5);
  535. dbSession.commit();
  536. underTest.deleteProject(dbSession, branch.uuid());
  537. dbSession.commit();
  538. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  539. assertThat(taskUuidsIn("ce_task_characteristics")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  540. underTest.deleteProject(dbSession, project.uuid());
  541. dbSession.commit();
  542. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  543. assertThat(taskUuidsIn("ce_task_characteristics")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  544. }
  545. @Test
  546. public void delete_row_in_ce_task_message_referring_to_a_row_in_ce_activity_when_deleting_project() {
  547. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  548. ComponentDto branch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  549. ComponentDto anotherBranch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  550. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  551. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  552. CeActivityDto projectTask = insertCeActivity(project);
  553. insertCeTaskMessages(projectTask.getUuid(), 3);
  554. CeActivityDto branchTask = insertCeActivity(branch);
  555. insertCeTaskMessages(branchTask.getUuid(), 2);
  556. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch);
  557. insertCeTaskMessages(anotherBranchTask.getUuid(), 6);
  558. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject);
  559. insertCeTaskMessages(anotherProjectTask.getUuid(), 2);
  560. insertCeTaskMessages("non existing task", 5);
  561. dbSession.commit();
  562. underTest.deleteProject(dbSession, branch.uuid());
  563. dbSession.commit();
  564. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  565. assertThat(taskUuidsIn("ce_task_message")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  566. underTest.deleteProject(dbSession, project.uuid());
  567. dbSession.commit();
  568. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  569. assertThat(taskUuidsIn("ce_task_message")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  570. }
  571. @Test
  572. public void delete_tasks_in_ce_queue_when_deleting_project() {
  573. ComponentDto projectToBeDeleted = db.components().insertPrivateProject();
  574. ComponentDto anotherLivingProject = db.components().insertPrivateProject();
  575. // Insert 3 rows in CE_QUEUE: two for the project that will be deleted (in order to check that status
  576. // is not involved in deletion), and one on another project
  577. dbClient.ceQueueDao().insert(dbSession, createCeQueue(projectToBeDeleted, Status.PENDING));
  578. dbClient.ceQueueDao().insert(dbSession, createCeQueue(projectToBeDeleted, Status.IN_PROGRESS));
  579. dbClient.ceQueueDao().insert(dbSession, createCeQueue(anotherLivingProject, Status.PENDING));
  580. dbSession.commit();
  581. underTest.deleteProject(dbSession, projectToBeDeleted.uuid());
  582. dbSession.commit();
  583. assertThat(db.countRowsOfTable("ce_queue")).isEqualTo(1);
  584. assertThat(db.countSql("select count(*) from ce_queue where main_component_uuid='" + projectToBeDeleted.uuid() + "'")).isEqualTo(0);
  585. }
  586. @Test
  587. public void delete_row_in_ce_task_input_referring_to_a_row_in_ce_queue_when_deleting_project() {
  588. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  589. ComponentDto branch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  590. ComponentDto anotherBranch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  591. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  592. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  593. CeQueueDto projectTask = insertCeQueue(project);
  594. insertCeTaskInput(projectTask.getUuid());
  595. CeQueueDto branchTask = insertCeQueue(branch);
  596. insertCeTaskInput(branchTask.getUuid());
  597. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch);
  598. insertCeTaskInput(anotherBranchTask.getUuid());
  599. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  600. insertCeTaskInput(anotherProjectTask.getUuid());
  601. insertCeTaskInput("non existing task");
  602. dbSession.commit();
  603. underTest.deleteProject(dbSession, branch.uuid());
  604. dbSession.commit();
  605. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  606. assertThat(taskUuidsIn("ce_task_input")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  607. underTest.deleteProject(dbSession, project.uuid());
  608. dbSession.commit();
  609. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  610. assertThat(taskUuidsIn("ce_task_input")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  611. }
  612. @Test
  613. public void delete_row_in_ce_scanner_context_referring_to_a_row_in_ce_queue_when_deleting_project() {
  614. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  615. ComponentDto branch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  616. ComponentDto anotherBranch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  617. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  618. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  619. CeQueueDto projectTask = insertCeQueue(project);
  620. insertCeScannerContext(projectTask.getUuid());
  621. CeQueueDto branchTask = insertCeQueue(branch);
  622. insertCeScannerContext(branchTask.getUuid());
  623. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch);
  624. insertCeScannerContext(anotherBranchTask.getUuid());
  625. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  626. insertCeScannerContext(anotherProjectTask.getUuid());
  627. insertCeScannerContext("non existing task");
  628. dbSession.commit();
  629. underTest.deleteProject(dbSession, branch.uuid());
  630. dbSession.commit();
  631. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  632. assertThat(taskUuidsIn("ce_scanner_context"))
  633. .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  634. underTest.deleteProject(dbSession, project.uuid());
  635. dbSession.commit();
  636. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  637. assertThat(taskUuidsIn("ce_scanner_context")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  638. }
  639. @Test
  640. public void delete_row_in_ce_task_characteristics_referring_to_a_row_in_ce_queue_when_deleting_project() {
  641. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  642. ComponentDto branch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  643. ComponentDto anotherBranch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  644. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  645. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  646. CeQueueDto projectTask = insertCeQueue(project);
  647. insertCeTaskCharacteristics(projectTask.getUuid(), 3);
  648. CeQueueDto branchTask = insertCeQueue(branch);
  649. insertCeTaskCharacteristics(branchTask.getUuid(), 1);
  650. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch);
  651. insertCeTaskCharacteristics(anotherBranchTask.getUuid(), 5);
  652. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  653. insertCeTaskCharacteristics(anotherProjectTask.getUuid(), 2);
  654. insertCeTaskCharacteristics("non existing task", 5);
  655. dbSession.commit();
  656. underTest.deleteProject(dbSession, branch.uuid());
  657. dbSession.commit();
  658. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  659. assertThat(taskUuidsIn("ce_task_characteristics"))
  660. .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  661. underTest.deleteProject(dbSession, project.uuid());
  662. dbSession.commit();
  663. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  664. assertThat(taskUuidsIn("ce_task_characteristics")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  665. }
  666. @Test
  667. public void delete_row_in_ce_task_message_referring_to_a_row_in_ce_queue_when_deleting_project() {
  668. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  669. ComponentDto branch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  670. ComponentDto anotherBranch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  671. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  672. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  673. CeQueueDto projectTask = insertCeQueue(project);
  674. insertCeTaskMessages(projectTask.getUuid(), 3);
  675. CeQueueDto branchTask = insertCeQueue(branch);
  676. insertCeTaskMessages(branchTask.getUuid(), 1);
  677. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch);
  678. insertCeTaskMessages(anotherBranchTask.getUuid(), 5);
  679. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  680. insertCeTaskMessages(anotherProjectTask.getUuid(), 2);
  681. insertCeTaskMessages("non existing task", 5);
  682. dbSession.commit();
  683. underTest.deleteProject(dbSession, branch.uuid());
  684. dbSession.commit();
  685. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  686. assertThat(taskUuidsIn("ce_task_message"))
  687. .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  688. underTest.deleteProject(dbSession, project.uuid());
  689. dbSession.commit();
  690. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  691. assertThat(taskUuidsIn("ce_task_message")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  692. }
  693. @Test
  694. public void delete_row_in_events_and_event_component_changes_when_deleting_project() {
  695. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  696. ComponentDto branch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  697. ComponentDto anotherBranch = ComponentTesting.newProjectBranch(project, newBranchDto(project));
  698. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  699. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  700. SnapshotDto projectAnalysis1 = db.components().insertSnapshot(project);
  701. SnapshotDto projectAnalysis2 = db.components().insertSnapshot(project);
  702. EventDto projectEvent1 = db.events().insertEvent(projectAnalysis1);
  703. EventDto projectEvent2 = db.events().insertEvent(projectAnalysis2);
  704. EventDto projectEvent3 = db.events().insertEvent(db.components().insertSnapshot(project));
  705. SnapshotDto branchAnalysis1 = db.components().insertSnapshot(branch);
  706. SnapshotDto branchAnalysis2 = db.components().insertSnapshot(branch);
  707. EventDto branchEvent1 = db.events().insertEvent(branchAnalysis1);
  708. EventDto branchEvent2 = db.events().insertEvent(branchAnalysis2);
  709. SnapshotDto anotherBranchAnalysis = db.components().insertSnapshot(anotherBranch);
  710. EventDto anotherBranchEvent = db.events().insertEvent(anotherBranchAnalysis);
  711. SnapshotDto anotherProjectAnalysis = db.components().insertSnapshot(anotherProject);
  712. EventDto anotherProjectEvent = db.events().insertEvent(anotherProjectAnalysis);
  713. ComponentDto referencedProjectA = db.components().insertPublicProject();
  714. ComponentDto referencedProjectB = db.components().insertPublicProject();
  715. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectA, null);
  716. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectB, null);
  717. BranchDto branchProjectA = newBranchDto(referencedProjectA);
  718. ComponentDto cptBranchProjectA = ComponentTesting.newProjectBranch(referencedProjectA, branchProjectA);
  719. db.events().insertEventComponentChanges(projectEvent2, projectAnalysis2, randomChangeCategory(), cptBranchProjectA, branchProjectA);
  720. // note: projectEvent3 has no component change
  721. db.events().insertEventComponentChanges(branchEvent1, branchAnalysis1, randomChangeCategory(), referencedProjectB, null);
  722. db.events().insertEventComponentChanges(branchEvent2, branchAnalysis2, randomChangeCategory(), cptBranchProjectA, branchProjectA);
  723. db.events().insertEventComponentChanges(anotherBranchEvent, anotherBranchAnalysis, randomChangeCategory(), referencedProjectB, null);
  724. db.events().insertEventComponentChanges(anotherProjectEvent, anotherProjectAnalysis, randomChangeCategory(), referencedProjectB, null);
  725. // deleting referenced project does not delete any data
  726. underTest.deleteProject(dbSession, referencedProjectA.uuid());
  727. assertThat(db.countRowsOfTable("event_component_changes"))
  728. .isEqualTo(7);
  729. assertThat(db.countRowsOfTable("events"))
  730. .isEqualTo(7);
  731. underTest.deleteProject(dbSession, branch.uuid());
  732. assertThat(uuidsIn("event_component_changes", "event_component_uuid"))
  733. .containsOnly(project.uuid(), anotherBranch.uuid(), anotherProject.uuid());
  734. assertThat(db.countRowsOfTable("event_component_changes"))
  735. .isEqualTo(5);
  736. assertThat(uuidsIn("events"))
  737. .containsOnly(projectEvent1.getUuid(), projectEvent2.getUuid(), projectEvent3.getUuid(), anotherBranchEvent.getUuid(), anotherProjectEvent.getUuid());
  738. underTest.deleteProject(dbSession, project.uuid());
  739. assertThat(uuidsIn("event_component_changes", "event_component_uuid"))
  740. .containsOnly(anotherBranch.uuid(), anotherProject.uuid());
  741. assertThat(db.countRowsOfTable("event_component_changes"))
  742. .isEqualTo(2);
  743. assertThat(uuidsIn("events"))
  744. .containsOnly(anotherBranchEvent.getUuid(), anotherProjectEvent.getUuid());
  745. }
  746. private static EventComponentChangeDto.ChangeCategory randomChangeCategory() {
  747. return EventComponentChangeDto.ChangeCategory.values()[new Random().nextInt(EventComponentChangeDto.ChangeCategory.values().length)];
  748. }
  749. private ComponentDto insertProjectWithBranchAndRelatedData() {
  750. RuleDefinitionDto rule = db.rules().insert();
  751. ComponentDto project = db.components().insertMainBranch();
  752. ComponentDto branch = db.components().insertProjectBranch(project);
  753. ComponentDto module = db.components().insertComponent(newModuleDto(branch));
  754. ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
  755. ComponentDto file = db.components().insertComponent(newFileDto(subModule));
  756. db.issues().insert(rule, branch, file);
  757. db.issues().insert(rule, branch, subModule);
  758. db.issues().insert(rule, branch, module);
  759. return project;
  760. }
  761. @Test
  762. public void delete_branch_content_when_deleting_project() {
  763. ComponentDto anotherLivingProject = insertProjectWithBranchAndRelatedData();
  764. int projectEntryCount = db.countRowsOfTable("projects");
  765. int issueCount = db.countRowsOfTable("issues");
  766. int branchCount = db.countRowsOfTable("project_branches");
  767. ComponentDto projectToDelete = insertProjectWithBranchAndRelatedData();
  768. assertThat(db.countRowsOfTable("projects")).isGreaterThan(projectEntryCount);
  769. assertThat(db.countRowsOfTable("issues")).isGreaterThan(issueCount);
  770. assertThat(db.countRowsOfTable("project_branches")).isGreaterThan(branchCount);
  771. underTest.deleteProject(dbSession, projectToDelete.uuid());
  772. dbSession.commit();
  773. assertThat(db.countRowsOfTable("projects")).isEqualTo(projectEntryCount);
  774. assertThat(db.countRowsOfTable("issues")).isEqualTo(issueCount);
  775. assertThat(db.countRowsOfTable("project_branches")).isEqualTo(branchCount);
  776. }
  777. @Test
  778. public void delete_view_and_child() {
  779. db.prepareDbUnit(getClass(), "view_sub_view_and_tech_project.xml");
  780. underTest.deleteProject(dbSession, "A");
  781. dbSession.commit();
  782. assertThat(db.countSql("select count(1) from projects where uuid='A'")).isZero();
  783. assertThat(db.countRowsOfTable("projects")).isZero();
  784. }
  785. @Test
  786. public void deleteProject_fails_with_IAE_if_specified_component_is_module() {
  787. ComponentDto privateProject = db.components().insertPrivateProject();
  788. ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(privateProject));
  789. expectedException.expect(IllegalArgumentException.class);
  790. expectedException.expectMessage("Couldn't find root component with uuid " + module.uuid());
  791. underTest.deleteProject(dbSession, module.uuid());
  792. }
  793. @Test
  794. public void deleteProject_fails_with_IAE_if_specified_component_is_directory() {
  795. ComponentDto privateProject = db.components().insertPrivateProject();
  796. ComponentDto directory = db.components().insertComponent(newDirectory(privateProject, "A/B"));
  797. expectedException.expect(IllegalArgumentException.class);
  798. expectedException.expectMessage("Couldn't find root component with uuid " + directory.uuid());
  799. underTest.deleteProject(dbSession, directory.uuid());
  800. }
  801. @Test
  802. public void deleteProject_fails_with_IAE_if_specified_component_is_file() {
  803. ComponentDto privateProject = db.components().insertPrivateProject();
  804. ComponentDto file = db.components().insertComponent(newFileDto(privateProject));
  805. expectedException.expect(IllegalArgumentException.class);
  806. expectedException.expectMessage("Couldn't find root component with uuid " + file.uuid());
  807. underTest.deleteProject(dbSession, file.uuid());
  808. }
  809. @Test
  810. public void deleteProject_fails_with_IAE_if_specified_component_is_subview() {
  811. ComponentDto view = db.components().insertView();
  812. ComponentDto subview = db.components().insertComponent(ComponentTesting.newSubView(view));
  813. expectedException.expect(IllegalArgumentException.class);
  814. expectedException.expectMessage("Couldn't find root component with uuid " + subview.uuid());
  815. underTest.deleteProject(dbSession, subview.uuid());
  816. }
  817. @Test
  818. public void delete_view_sub_view_and_tech_project() {
  819. db.prepareDbUnit(getClass(), "view_sub_view_and_tech_project.xml");
  820. // view
  821. underTest.deleteProject(dbSession, "A");
  822. dbSession.commit();
  823. assertThat(db.countSql("select count(1) from projects where uuid='A'")).isZero();
  824. }
  825. @Test
  826. public void should_delete_old_closed_issues() {
  827. RuleDefinitionDto rule = db.rules().insert();
  828. ComponentDto project = db.components().insertMainBranch();
  829. ComponentDto module = db.components().insertComponent(newModuleDto(project));
  830. ComponentDto file = db.components().insertComponent(newFileDto(module));
  831. IssueDto oldClosed = db.issues().insert(rule, project, file, issue -> {
  832. issue.setStatus("CLOSED");
  833. issue.setIssueCloseDate(DateUtils.addDays(new Date(), -31));
  834. });
  835. IssueDto notOldEnoughClosed = db.issues().insert(rule, project, file, issue -> {
  836. issue.setStatus("CLOSED");
  837. issue.setIssueCloseDate(new Date());
  838. });
  839. IssueDto notClosed = db.issues().insert(rule, project, file);
  840. when(system2.now()).thenReturn(new Date().getTime());
  841. underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
  842. dbSession.commit();
  843. // old closed got deleted
  844. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, oldClosed.getKey())).isEmpty();
  845. // others remain
  846. assertThat(db.countRowsOfTable("issues")).isEqualTo(2);
  847. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, notOldEnoughClosed.getKey())).isNotEmpty();
  848. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, notClosed.getKey())).isNotEmpty();
  849. }
  850. @Test
  851. public void deleteProject_deletes_webhook_deliveries() {
  852. ComponentDto project = db.components().insertPublicProject();
  853. dbClient.webhookDeliveryDao().insert(dbSession, newDto().setComponentUuid(project.uuid()).setUuid("D1").setDurationMs(1000).setWebhookUuid("webhook-uuid"));
  854. dbClient.webhookDeliveryDao().insert(dbSession, newDto().setComponentUuid("P2").setUuid("D2").setDurationMs(1000).setWebhookUuid("webhook-uuid"));
  855. underTest.deleteProject(dbSession, project.uuid());
  856. assertThat(selectAllDeliveryUuids(db, dbSession)).containsOnly("D2");
  857. }
  858. @Test
  859. public void deleteProject_deletes_project_mappings() {
  860. ComponentDto project = db.components().insertPublicProject();
  861. dbClient.projectMappingsDao().put(dbSession, "a.key.type", "a.key", project.uuid());
  862. dbClient.projectMappingsDao().put(dbSession, "a.key.type", "another.key", "D2");
  863. underTest.deleteProject(dbSession, project.uuid());
  864. assertThat(dbClient.projectMappingsDao().get(dbSession, "a.key.type", "a.key")).isEmpty();
  865. assertThat(dbClient.projectMappingsDao().get(dbSession, "a.key.type", "another.key")).isNotEmpty();
  866. }
  867. @Test
  868. public void deleteProject_deletes_project_alm_bindings() {
  869. ALM alm = ALM.GITHUB;
  870. String repoId = "123";
  871. String otherRepoId = repoId + "-foo";
  872. ComponentDto project = db.components().insertPublicProject();
  873. ComponentDto otherProject = db.components().insertPublicProject();
  874. dbClient.projectAlmBindingsDao().insertOrUpdate(dbSession, alm, repoId, project.uuid(), null, "foo");
  875. dbClient.projectAlmBindingsDao().insertOrUpdate(dbSession, alm, otherRepoId, otherProject.uuid(), null, "bar");
  876. underTest.deleteProject(dbSession, project.uuid());
  877. assertThat(dbClient.projectAlmBindingsDao().findProjectKey(dbSession, alm, repoId)).isEmpty();
  878. assertThat(dbClient.projectAlmBindingsDao().findProjectKey(dbSession, alm, otherRepoId)).isNotEmpty();
  879. }
  880. @Test
  881. public void deleteNonRootComponents_has_no_effect_when_parameter_is_empty() {
  882. DbSession dbSession = mock(DbSession.class);
  883. underTest.deleteNonRootComponentsInView(dbSession, Collections.emptyList());
  884. verifyZeroInteractions(dbSession);
  885. }
  886. @Test
  887. public void deleteNonRootComponents_has_no_effect_when_parameter_contains_only_projects_and_or_views() {
  888. ComponentDbTester componentDbTester = db.components();
  889. verifyNoEffect(componentDbTester.insertPrivateProject());
  890. verifyNoEffect(componentDbTester.insertPublicProject());
  891. verifyNoEffect(componentDbTester.insertView());
  892. verifyNoEffect(componentDbTester.insertView(), componentDbTester.insertPrivateProject(), componentDbTester.insertPublicProject());
  893. }
  894. @Test
  895. public void delete_live_measures_when_deleting_project() {
  896. MetricDto metric = db.measures().insertMetric();
  897. ComponentDto project1 = db.components().insertPublicProject();
  898. ComponentDto module1 = db.components().insertComponent(ComponentTesting.newModuleDto(project1));
  899. db.measures().insertLiveMeasure(project1, metric);
  900. db.measures().insertLiveMeasure(module1, metric);
  901. ComponentDto project2 = db.components().insertPublicProject();
  902. ComponentDto module2 = db.components().insertComponent(ComponentTesting.newModuleDto(project2));
  903. db.measures().insertLiveMeasure(project2, metric);
  904. db.measures().insertLiveMeasure(module2, metric);
  905. underTest.deleteProject(dbSession, project1.uuid());
  906. assertThat(dbClient.liveMeasureDao().selectByComponentUuidsAndMetricIds(dbSession, asList(project1.uuid(), module1.uuid()), asList(metric.getId()))).isEmpty();
  907. assertThat(dbClient.liveMeasureDao().selectByComponentUuidsAndMetricIds(dbSession, asList(project2.uuid(), module2.uuid()), asList(metric.getId()))).hasSize(2);
  908. }
  909. private void verifyNoEffect(ComponentDto firstRoot, ComponentDto... otherRoots) {
  910. DbSession dbSession = mock(DbSession.class);
  911. List<ComponentDto> componentDtos = Stream.concat(Stream.of(firstRoot), Arrays.stream(otherRoots)).collect(Collectors.toList());
  912. Collections.shuffle(componentDtos); // order of collection must not matter
  913. underTest.deleteNonRootComponentsInView(dbSession, componentDtos);
  914. verifyZeroInteractions(dbSession);
  915. }
  916. @Test
  917. public void deleteNonRootComponents_deletes_only_non_root_components_of_a_project_from_table_PROJECTS() {
  918. ComponentDto project = new Random().nextBoolean() ? db.components().insertPublicProject() : db.components().insertPrivateProject();
  919. ComponentDto module1 = db.components().insertComponent(ComponentTesting.newModuleDto(project));
  920. ComponentDto module2 = db.components().insertComponent(ComponentTesting.newModuleDto(module1));
  921. ComponentDto dir1 = db.components().insertComponent(newDirectory(module1, "A/B"));
  922. List<ComponentDto> components = asList(
  923. project,
  924. module1,
  925. module2,
  926. dir1,
  927. db.components().insertComponent(newDirectory(module2, "A/C")),
  928. db.components().insertComponent(newFileDto(dir1)),
  929. db.components().insertComponent(newFileDto(module2)),
  930. db.components().insertComponent(newFileDto(project)));
  931. Collections.shuffle(components);
  932. underTest.deleteNonRootComponentsInView(dbSession, components);
  933. assertThat(uuidsIn("projects"))
  934. .containsOnly(project.uuid());
  935. }
  936. @Test
  937. public void deleteNonRootComponents_deletes_only_non_root_components_of_a_view_from_table_PROJECTS() {
  938. ComponentDto[] projects = {
  939. db.components().insertPrivateProject(),
  940. db.components().insertPrivateProject(),
  941. db.components().insertPrivateProject()
  942. };
  943. ComponentDto view = db.components().insertView();
  944. ComponentDto subview1 = db.components().insertComponent(ComponentTesting.newSubView(view));
  945. ComponentDto subview2 = db.components().insertComponent(ComponentTesting.newSubView(subview1));
  946. List<ComponentDto> components = asList(
  947. view,
  948. subview1,
  949. subview2,
  950. db.components().insertComponent(newProjectCopy("a", projects[0], view)),
  951. db.components().insertComponent(newProjectCopy("b", projects[1], subview1)),
  952. db.components().insertComponent(newProjectCopy("c", projects[2], subview2)));
  953. Collections.shuffle(components);
  954. underTest.deleteNonRootComponentsInView(dbSession, components);
  955. assertThat(uuidsIn("projects"))
  956. .containsOnly(view.uuid(), projects[0].uuid(), projects[1].uuid(), projects[2].uuid());
  957. }
  958. @Test
  959. public void deleteNonRootComponents_deletes_only_specified_non_root_components_of_a_project_from_table_PROJECTS() {
  960. ComponentDto project = new Random().nextBoolean() ? db.components().insertPublicProject() : db.components().insertPrivateProject();
  961. ComponentDto module1 = db.components().insertComponent(ComponentTesting.newModuleDto(project));
  962. ComponentDto module2 = db.components().insertComponent(ComponentTesting.newModuleDto(module1));
  963. ComponentDto dir1 = db.components().insertComponent(newDirectory(module1, "A/B"));
  964. ComponentDto dir2 = db.components().insertComponent(newDirectory(module2, "A/C"));
  965. ComponentDto file1 = db.components().insertComponent(newFileDto(dir1));
  966. ComponentDto file2 = db.components().insertComponent(newFileDto(module2));
  967. ComponentDto file3 = db.components().insertComponent(newFileDto(project));
  968. underTest.deleteNonRootComponentsInView(dbSession, singletonList(file3));
  969. assertThat(uuidsIn("projects"))
  970. .containsOnly(project.uuid(), module1.uuid(), module2.uuid(), dir1.uuid(), dir2.uuid(), file1.uuid(), file2.uuid());
  971. underTest.deleteNonRootComponentsInView(dbSession, asList(module1, dir2, file1));
  972. assertThat(uuidsIn("projects"))
  973. .containsOnly(project.uuid(), module2.uuid(), dir1.uuid(), file2.uuid());
  974. }
  975. @Test
  976. public void deleteNonRootComponents_deletes_only_specified_non_root_components_of_a_view_from_table_PROJECTS() {
  977. ComponentDto[] projects = {
  978. db.components().insertPrivateProject(),
  979. db.components().insertPrivateProject(),
  980. db.components().insertPrivateProject()
  981. };
  982. ComponentDto view = db.components().insertView();
  983. ComponentDto subview1 = db.components().insertComponent(ComponentTesting.newSubView(view));
  984. ComponentDto subview2 = db.components().insertComponent(ComponentTesting.newSubView(subview1));
  985. ComponentDto pc1 = db.components().insertComponent(newProjectCopy("a", projects[0], view));
  986. ComponentDto pc2 = db.components().insertComponent(newProjectCopy("b", projects[1], subview1));
  987. ComponentDto pc3 = db.components().insertComponent(newProjectCopy("c", projects[2], subview2));
  988. underTest.deleteNonRootComponentsInView(dbSession, singletonList(pc3));
  989. assertThat(uuidsIn("projects"))
  990. .containsOnly(view.uuid(), projects[0].uuid(), projects[1].uuid(), projects[2].uuid(),
  991. subview1.uuid(), subview2.uuid(), pc1.uuid(), pc2.uuid());
  992. underTest.deleteNonRootComponentsInView(dbSession, asList(subview1, pc2));
  993. assertThat(uuidsIn("projects"))
  994. .containsOnly(view.uuid(), projects[0].uuid(), projects[1].uuid(), projects[2].uuid(), subview2.uuid(), pc1.uuid());
  995. }
  996. @Test
  997. public void deleteNonRootComponents_deletes_measures_of_any_non_root_component_of_a_view() {
  998. ComponentDto view = db.components().insertView();
  999. ComponentDto subview = db.components().insertComponent(ComponentTesting.newSubView(view));
  1000. ComponentDto pc = db.components().insertComponent(newProjectCopy("a", db.components().insertPrivateProject(), view));
  1001. insertMeasureFor(view, subview, pc);
  1002. assertThat(getComponentUuidsOfMeasures()).containsOnly(view.uuid(), subview.uuid(), pc.uuid());
  1003. underTest.deleteNonRootComponentsInView(dbSession, singletonList(pc));
  1004. assertThat(getComponentUuidsOfMeasures())
  1005. .containsOnly(view.uuid(), subview.uuid());
  1006. underTest.deleteNonRootComponentsInView(dbSession, singletonList(subview));
  1007. assertThat(getComponentUuidsOfMeasures())
  1008. .containsOnly(view.uuid());
  1009. }
  1010. @Test
  1011. public void deleteNonRootComponents_deletes_properties_of_subviews_of_a_view() {
  1012. ComponentDto view = db.components().insertView();
  1013. ComponentDto subview1 = db.components().insertComponent(ComponentTesting.newSubView(view));
  1014. ComponentDto subview2 = db.components().insertComponent(ComponentTesting.newSubView(subview1));
  1015. ComponentDto subview3 = db.components().insertComponent(ComponentTesting.newSubView(view));
  1016. ComponentDto pc = db.components().insertComponent(newProjectCopy("a", db.components().insertPrivateProject(), view));
  1017. insertPropertyFor(view, subview1, subview2, subview3, pc);
  1018. assertThat(getResourceIdOfProperties()).containsOnly(view.getId(), subview1.getId(), subview2.getId(), subview3.getId(), pc.getId());
  1019. underTest.deleteNonRootComponentsInView(dbSession, singletonList(subview1));
  1020. assertThat(getResourceIdOfProperties())
  1021. .containsOnly(view.getId(), subview2.getId(), subview3.getId(), pc.getId());
  1022. underTest.deleteNonRootComponentsInView(dbSession, asList(subview2, subview3, pc));
  1023. assertThat(getResourceIdOfProperties())
  1024. .containsOnly(view.getId(), pc.getId());
  1025. }
  1026. @Test
  1027. public void deleteNonRootComponentsInView_deletes_manual_measures_of_subviews_of_a_view() {
  1028. ComponentDto view = db.components().insertView();
  1029. ComponentDto subview1 = db.components().insertComponent(ComponentTesting.newSubView(view));
  1030. ComponentDto subview2 = db.components().insertComponent(ComponentTesting.newSubView(subview1));
  1031. ComponentDto subview3 = db.components().insertComponent(ComponentTesting.newSubView(view));
  1032. ComponentDto pc = db.components().insertComponent(newProjectCopy("a", db.components().insertPrivateProject(), view));
  1033. insertManualMeasureFor(view, subview1, subview2, subview3, pc);
  1034. assertThat(getComponentUuidsOfManualMeasures()).containsOnly(view.uuid(), subview1.uuid(), subview2.uuid(), subview3.uuid(), pc.uuid());
  1035. underTest.deleteNonRootComponentsInView(dbSession, singletonList(subview1));
  1036. assertThat(getComponentUuidsOfManualMeasures())
  1037. .containsOnly(view.uuid(), subview2.uuid(), subview3.uuid(), pc.uuid());
  1038. underTest.deleteNonRootComponentsInView(dbSession, asList(subview2, subview3, pc));
  1039. assertThat(getComponentUuidsOfManualMeasures())
  1040. .containsOnly(view.uuid(), pc.uuid());
  1041. }
  1042. private void insertManualMeasureFor(ComponentDto... componentDtos) {
  1043. Arrays.stream(componentDtos).forEach(componentDto -> dbClient.customMeasureDao().insert(dbSession, new CustomMeasureDto()
  1044. .setComponentUuid(componentDto.uuid())
  1045. .setMetricId(new Random().nextInt())));
  1046. dbSession.commit();
  1047. }
  1048. private Stream<String> getComponentUuidsOfManualMeasures() {
  1049. return db.select("select component_uuid as \"COMPONENT_UUID\" from manual_measures").stream()
  1050. .map(row -> (String) row.get("COMPONENT_UUID"));
  1051. }
  1052. private Stream<Long> getResourceIdOfProperties() {
  1053. return db.select("select resource_id as \"ID\" from properties").stream()
  1054. .map(row -> (Long) row.get("ID"));
  1055. }
  1056. private void insertPropertyFor(ComponentDto... components) {
  1057. Stream.of(components).forEach(componentDto -> db.properties().insertProperty(new PropertyDto()
  1058. .setKey(randomAlphabetic(3))
  1059. .setValue(randomAlphabetic(3))
  1060. .setResourceId(componentDto.getId())));
  1061. }
  1062. private Stream<String> getComponentUuidsOfMeasures() {
  1063. return db.select("select component_uuid as \"COMPONENT_UUID\" from project_measures").stream()
  1064. .map(row -> (String) row.get("COMPONENT_UUID"));
  1065. }
  1066. private void insertMeasureFor(ComponentDto... components) {
  1067. Arrays.stream(components).forEach(componentDto -> db.getDbClient().measureDao().insert(dbSession, new MeasureDto()
  1068. .setMetricId(new Random().nextInt())
  1069. .setComponentUuid(componentDto.uuid())
  1070. .setAnalysisUuid(randomAlphabetic(3))));
  1071. dbSession.commit();
  1072. }
  1073. private CeQueueDto createCeQueue(ComponentDto component, Status status) {
  1074. CeQueueDto queueDto = new CeQueueDto();
  1075. queueDto.setUuid(Uuids.create());
  1076. queueDto.setTaskType(REPORT);
  1077. queueDto.setComponentUuid(component.uuid());
  1078. queueDto.setMainComponentUuid(firstNonNull(component.getMainBranchProjectUuid(), component.uuid()));
  1079. queueDto.setSubmitterUuid("submitter uuid");
  1080. queueDto.setCreatedAt(1_300_000_000_000L);
  1081. queueDto.setStatus(status);
  1082. return queueDto;
  1083. }
  1084. private CeActivityDto insertCeActivity(ComponentDto component) {
  1085. Status unusedStatus = Status.values()[RandomUtils.nextInt(Status.values().length)];
  1086. CeQueueDto queueDto = createCeQueue(component, unusedStatus);
  1087. CeActivityDto dto = new CeActivityDto(queueDto);
  1088. dto.setStatus(CeActivityDto.Status.SUCCESS);
  1089. dto.setStartedAt(1_500_000_000_000L);
  1090. dto.setExecutedAt(1_500_000_000_500L);
  1091. dto.setExecutionTimeMs(500L);
  1092. dbClient.ceActivityDao().insert(dbSession, dto);
  1093. return dto;
  1094. }
  1095. private CeQueueDto insertCeQueue(ComponentDto component) {
  1096. CeQueueDto res = new CeQueueDto()
  1097. .setUuid(UuidFactoryFast.getInstance().create())
  1098. .setTaskType("foo")
  1099. .setComponentUuid(component.uuid())
  1100. .setMainComponentUuid(firstNonNull(component.getMainBranchProjectUuid(), component.uuid()))
  1101. .setStatus(Status.PENDING)
  1102. .setCreatedAt(1_2323_222L)
  1103. .setUpdatedAt(1_2323_222L);
  1104. dbClient.ceQueueDao().insert(dbSession, res);
  1105. dbSession.commit();
  1106. return res;
  1107. }
  1108. private void insertCeScannerContext(String uuid) {
  1109. dbClient.ceScannerContextDao().insert(dbSession, uuid, CloseableIterator.from(Arrays.asList("a", "b", "c").iterator()));
  1110. dbSession.commit();
  1111. }
  1112. private void insertCeTaskCharacteristics(String uuid, int count) {
  1113. List<CeTaskCharacteristicDto> dtos = IntStream.range(0, count)
  1114. .mapToObj(i -> new CeTaskCharacteristicDto()
  1115. .setUuid(UuidFactoryFast.getInstance().create())
  1116. .setTaskUuid(uuid)
  1117. .setKey("key_" + uuid.hashCode() + i)
  1118. .setValue("value_" + uuid.hashCode() + i))
  1119. .collect(Collectors.toList());
  1120. dbClient.ceTaskCharacteristicsDao().insert(dbSession, dtos);
  1121. dbSession.commit();
  1122. }
  1123. private void insertCeTaskInput(String uuid) {
  1124. dbClient.ceTaskInputDao().insert(dbSession, uuid, new ByteArrayInputStream("some content man!".getBytes()));
  1125. dbSession.commit();
  1126. }
  1127. private void insertCeTaskMessages(String uuid, int count) {
  1128. IntStream.range(0, count)
  1129. .mapToObj(i -> new CeTaskMessageDto()
  1130. .setUuid(UuidFactoryFast.getInstance().create())
  1131. .setTaskUuid(uuid)
  1132. .setMessage("key_" + uuid.hashCode() + i)
  1133. .setCreatedAt(2_333_444L + i))
  1134. .forEach(dto -> dbClient.ceTaskMessageDao().insert(dbSession, dto));
  1135. dbSession.commit();
  1136. }
  1137. private static PurgeableAnalysisDto getById(List<PurgeableAnalysisDto> snapshots, String uuid) {
  1138. return snapshots.stream()
  1139. .filter(snapshot -> uuid.equals(snapshot.getAnalysisUuid()))
  1140. .findFirst()
  1141. .orElse(null);
  1142. }
  1143. private Stream<String> uuidsIn(String tableName) {
  1144. return uuidsIn(tableName, "uuid");
  1145. }
  1146. private Stream<String> taskUuidsIn(String tableName) {
  1147. return uuidsIn(tableName, "task_uuid");
  1148. }
  1149. private Stream<String> uuidsIn(String tableName, String columnName) {
  1150. return db.select("select " + columnName + " as \"UUID\" from " + tableName)
  1151. .stream()
  1152. .map(row -> (String) row.get("UUID"));
  1153. }
  1154. private static PurgeConfiguration newConfigurationWith30Days() {
  1155. return new PurgeConfiguration(PROJECT_UUID, PROJECT_UUID, emptyList(), 30, Optional.of(30), System2.INSTANCE, Collections.emptyList());
  1156. }
  1157. private static PurgeConfiguration newConfigurationWith30Days(System2 system2, String rootUuid, String projectUuid, String... disabledComponentUuids) {
  1158. return new PurgeConfiguration(rootUuid, projectUuid, emptyList(), 30, Optional.of(30), system2, asList(disabledComponentUuids));
  1159. }
  1160. }