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.

PurgeDaoIT.java 110KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2023 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.ImmutableSet;
  22. import java.io.ByteArrayInputStream;
  23. import java.io.IOException;
  24. import java.time.LocalDateTime;
  25. import java.time.ZoneOffset;
  26. import java.util.ArrayList;
  27. import java.util.Arrays;
  28. import java.util.Collection;
  29. import java.util.Collections;
  30. import java.util.Date;
  31. import java.util.List;
  32. import java.util.Optional;
  33. import java.util.Random;
  34. import java.util.Set;
  35. import java.util.function.Consumer;
  36. import java.util.stream.Collectors;
  37. import java.util.stream.IntStream;
  38. import java.util.stream.Stream;
  39. import org.apache.commons.io.IOUtils;
  40. import org.apache.commons.lang.math.RandomUtils;
  41. import org.apache.commons.lang.time.DateUtils;
  42. import org.junit.Rule;
  43. import org.junit.Test;
  44. import org.slf4j.event.Level;
  45. import org.sonar.api.issue.Issue;
  46. import org.sonar.api.resources.Qualifiers;
  47. import org.sonar.api.testfixtures.log.LogAndArguments;
  48. import org.sonar.api.testfixtures.log.LogTester;
  49. import org.sonar.api.utils.System2;
  50. import org.sonar.api.utils.log.LoggerLevel;
  51. import org.sonar.core.util.CloseableIterator;
  52. import org.sonar.core.util.UuidFactoryFast;
  53. import org.sonar.core.util.Uuids;
  54. import org.sonar.db.DbClient;
  55. import org.sonar.db.DbInputStream;
  56. import org.sonar.db.DbSession;
  57. import org.sonar.db.DbTester;
  58. import org.sonar.db.alm.setting.AlmSettingDto;
  59. import org.sonar.db.ce.CeActivityDto;
  60. import org.sonar.db.ce.CeQueueDto;
  61. import org.sonar.db.ce.CeQueueDto.Status;
  62. import org.sonar.db.ce.CeTaskCharacteristicDto;
  63. import org.sonar.db.ce.CeTaskMessageDto;
  64. import org.sonar.db.ce.CeTaskMessageType;
  65. import org.sonar.db.ce.CeTaskTypes;
  66. import org.sonar.db.component.BranchDto;
  67. import org.sonar.db.component.BranchType;
  68. import org.sonar.db.component.ComponentDbTester;
  69. import org.sonar.db.component.ComponentDto;
  70. import org.sonar.db.component.ComponentTesting;
  71. import org.sonar.db.component.ProjectData;
  72. import org.sonar.db.component.SnapshotDto;
  73. import org.sonar.db.event.EventComponentChangeDto;
  74. import org.sonar.db.event.EventDto;
  75. import org.sonar.db.event.EventTesting;
  76. import org.sonar.db.issue.IssueChangeDto;
  77. import org.sonar.db.issue.IssueDto;
  78. import org.sonar.db.measure.LiveMeasureDto;
  79. import org.sonar.db.measure.MeasureDto;
  80. import org.sonar.db.metric.MetricDto;
  81. import org.sonar.db.newcodeperiod.NewCodePeriodDto;
  82. import org.sonar.db.newcodeperiod.NewCodePeriodType;
  83. import org.sonar.db.portfolio.PortfolioProjectDto;
  84. import org.sonar.db.project.ProjectDto;
  85. import org.sonar.db.property.PropertyDto;
  86. import org.sonar.db.report.ReportScheduleDto;
  87. import org.sonar.db.report.ReportSubscriptionDto;
  88. import org.sonar.db.rule.RuleDto;
  89. import org.sonar.db.source.FileSourceDto;
  90. import org.sonar.db.user.UserDismissedMessageDto;
  91. import org.sonar.db.user.UserDto;
  92. import org.sonar.db.webhook.WebhookDeliveryLiteDto;
  93. import org.sonar.db.webhook.WebhookDto;
  94. import static java.nio.charset.StandardCharsets.UTF_8;
  95. import static java.time.ZoneOffset.UTC;
  96. import static java.util.Arrays.asList;
  97. import static java.util.Collections.singletonList;
  98. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  99. import static org.assertj.core.api.Assertions.assertThat;
  100. import static org.assertj.core.groups.Tuple.tuple;
  101. import static org.mockito.Mockito.mock;
  102. import static org.mockito.Mockito.verifyNoInteractions;
  103. import static org.mockito.Mockito.when;
  104. import static org.sonar.db.ce.CeTaskTypes.REPORT;
  105. import static org.sonar.db.component.ComponentTesting.newBranchDto;
  106. import static org.sonar.db.component.ComponentTesting.newDirectory;
  107. import static org.sonar.db.component.ComponentTesting.newFileDto;
  108. import static org.sonar.db.component.ComponentTesting.newProjectCopy;
  109. import static org.sonar.db.component.ComponentTesting.newSubPortfolio;
  110. import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED;
  111. import static org.sonar.db.component.SnapshotDto.STATUS_UNPROCESSED;
  112. import static org.sonar.db.component.SnapshotTesting.newSnapshot;
  113. import static org.sonar.db.event.EventDto.CATEGORY_VERSION;
  114. import static org.sonar.db.issue.IssueTesting.newCodeReferenceIssue;
  115. import static org.sonar.db.webhook.WebhookDeliveryTesting.newDto;
  116. import static org.sonar.db.webhook.WebhookDeliveryTesting.selectAllDeliveryUuids;
  117. public class PurgeDaoIT {
  118. private static final String PROJECT_UUID = "P1";
  119. private final System2 system2 = mock(System2.class);
  120. @Rule
  121. public DbTester db = DbTester.create(system2);
  122. @Rule
  123. public LogTester logTester = new LogTester();
  124. private final DbClient dbClient = db.getDbClient();
  125. private final DbSession dbSession = db.getSession();
  126. private final PurgeDao underTest = db.getDbClient().purgeDao();
  127. @Test
  128. public void purge_failed_ce_tasks() {
  129. ProjectData project = db.components().insertPrivateProject();
  130. SnapshotDto pastAnalysis = db.components().insertSnapshot(project.getMainBranchComponent(), t -> t.setStatus(STATUS_PROCESSED).setLast(false));
  131. db.components().insertSnapshot(project.getMainBranchComponent(), t -> t.setStatus(STATUS_UNPROCESSED).setLast(false));
  132. SnapshotDto lastAnalysis = db.components().insertSnapshot(project.getMainBranchComponent(), t -> t.setStatus(STATUS_PROCESSED).setLast(true));
  133. underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, project.getMainBranchComponent().uuid(), project.projectUuid()), PurgeListener.EMPTY, new PurgeProfiler());
  134. dbSession.commit();
  135. assertThat(uuidsOfAnalysesOfRoot(project.getMainBranchComponent())).containsOnly(pastAnalysis.getUuid(), lastAnalysis.getUuid());
  136. }
  137. /**
  138. * SONAR-17720
  139. */
  140. @Test
  141. public void purge_inactive_branches_should_not_purge_newly_created_branches() {
  142. when(system2.now()).thenReturn(new Date().getTime());
  143. ProjectData project = db.components().insertPublicProject();
  144. // new branch without a snapshot (analysis not processed yet)
  145. BranchDto pr1 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.PULL_REQUEST));
  146. underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, project.getMainBranchComponent().branchUuid(), project.getProjectDto().getUuid()), PurgeListener.EMPTY, new PurgeProfiler());
  147. dbSession.commit();
  148. // pr not purged
  149. assertThat(uuidsIn("components")).containsOnly(project.getMainBranchDto().getUuid(), pr1.getUuid());
  150. assertThat(uuidsIn("project_branches")).containsOnly(project.getMainBranchDto().getUuid(), pr1.getUuid());
  151. }
  152. @Test
  153. public void purge_inactive_branches() {
  154. Date date31DaysAgo = DateUtils.addDays(new Date(), -31);
  155. when(system2.now()).thenReturn(new Date().getTime());
  156. RuleDto rule = db.rules().insert();
  157. ProjectData project = db.components().insertPublicProject();
  158. BranchDto branch1 = db.components().insertProjectBranch(project.getProjectDto());
  159. BranchDto branch2 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH));
  160. BranchDto pr1 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.PULL_REQUEST));
  161. db.components().insertSnapshot(branch1);
  162. db.components().insertSnapshot(branch2);
  163. db.components().insertSnapshot(pr1);
  164. // branch with other components and issues, last analysed 31 days ago
  165. BranchDto branch3 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH).setExcludeFromPurge(false));
  166. addComponentsSnapshotsAndIssuesToBranch(branch3, rule, 31);
  167. // branch with no analysis
  168. BranchDto branch4 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH));
  169. // branch last analysed 31 days ago but protected from purge
  170. BranchDto branch5 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH).setExcludeFromPurge(true));
  171. db.components().insertSnapshot(branch5, dto -> dto.setCreatedAt(date31DaysAgo.getTime()));
  172. // pull request last analysed 100 days ago
  173. BranchDto pr2 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.PULL_REQUEST).setExcludeFromPurge(false));
  174. addComponentsSnapshotsAndIssuesToBranch(pr2, rule, 100);
  175. // pull request last analysed 100 days ago but marked as "excluded from purge" which should not work for pull requests
  176. BranchDto pr3 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.PULL_REQUEST).setExcludeFromPurge(true));
  177. addComponentsSnapshotsAndIssuesToBranch(pr3, rule, 100);
  178. updateBranchCreationDate(date31DaysAgo, branch1.getUuid(), branch2.getUuid(), branch3.getUuid(), branch4.getUuid(), branch5.getUuid(), pr1.getUuid(), pr2.getUuid(), pr3.getUuid());
  179. underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, project.getMainBranchDto().getUuid(), project.getProjectDto().getUuid()), PurgeListener.EMPTY, new PurgeProfiler());
  180. dbSession.commit();
  181. assertThat(uuidsIn("components")).containsOnly(
  182. project.getMainBranchDto().getUuid(), branch1.getUuid(), branch2.getUuid(), branch5.getUuid(), pr1.getUuid());
  183. assertThat(uuidsIn("projects")).containsOnly(project.getProjectDto().getUuid());
  184. }
  185. private void updateBranchCreationDate(Date date, String... branchUuids) {
  186. for (String branchUuid : branchUuids) {
  187. db.executeUpdateSql("update project_branches set created_at = '" + date.getTime() + "' where uuid = '" + branchUuid + "'");
  188. }
  189. db.getSession().commit();
  190. }
  191. @Test
  192. public void purge_inactive_pull_request() {
  193. RuleDto rule = db.rules().insert();
  194. ProjectData project = db.components().insertPublicProject();
  195. BranchDto nonMainBranch = db.components().insertProjectBranch(project.getProjectDto());
  196. db.components().insertSnapshot(nonMainBranch);
  197. BranchDto recentPullRequest = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.PULL_REQUEST));
  198. db.components().insertSnapshot(recentPullRequest);
  199. // pull request with other components and issues, updated 31 days ago
  200. BranchDto pullRequest = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.PULL_REQUEST));
  201. db.components().insertSnapshot(pullRequest, dto -> dto.setCreatedAt(DateUtils.addDays(new Date(), -31).getTime()));
  202. ComponentDto pullRequestComponent = db.components().getComponentDto(pullRequest);
  203. ComponentDto dir = db.components().insertComponent(newDirectory(pullRequestComponent, "path"));
  204. ComponentDto file = db.components().insertComponent(newFileDto(pullRequestComponent, dir));
  205. db.issues().insert(rule, pullRequestComponent, file);
  206. underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, project.getMainBranchComponent().branchUuid(), project.getProjectDto().getUuid()), PurgeListener.EMPTY, new PurgeProfiler());
  207. dbSession.commit();
  208. assertThat(uuidsIn("components")).containsOnly(project.getMainBranchDto().getUuid(), nonMainBranch.getUuid(), recentPullRequest.getUuid());
  209. assertThat(uuidsIn("projects")).containsOnly(project.getProjectDto().getUuid());
  210. }
  211. @Test
  212. public void purge_inactive_branches_when_analyzing_non_main_branch() {
  213. RuleDto rule = db.rules().insert();
  214. ProjectData project = db.components().insertPublicProject();
  215. BranchDto nonMainBranch = db.components().insertProjectBranch(project.getProjectDto());
  216. db.components().insertSnapshot(nonMainBranch);
  217. // branch updated 31 days ago
  218. BranchDto branch1 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH));
  219. db.components().insertSnapshot(branch1, dto -> dto.setCreatedAt(DateUtils.addDays(new Date(), -31).getTime()));
  220. // branches with other components and issues, updated 31 days ago
  221. BranchDto branch2 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.PULL_REQUEST));
  222. db.components().insertSnapshot(branch2, dto -> dto.setCreatedAt(DateUtils.addDays(new Date(), -31).getTime()));
  223. ComponentDto branch2Component = db.components().getComponentDto(branch2);
  224. ComponentDto file = db.components().insertComponent(newFileDto(branch2Component));
  225. db.issues().insert(rule, branch2Component, file);
  226. BranchDto branch3 = db.components().insertProjectBranch(project.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH));
  227. db.components().insertSnapshot(branch3, dto -> dto.setCreatedAt(DateUtils.addDays(new Date(), -31).getTime()));
  228. // properties exist or active and for inactive branch
  229. ComponentDto branch1Component = db.components().getComponentDto(branch1);
  230. ComponentDto branch3Component = db.components().getComponentDto(branch3);
  231. insertPropertyFor(branch3Component, branch1Component);
  232. // analysing branch1
  233. underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, branch1.getUuid(), project.getProjectDto().getUuid()), PurgeListener.EMPTY, new PurgeProfiler());
  234. dbSession.commit();
  235. // branch1 wasn't deleted since it was being analyzed!
  236. assertThat(uuidsIn("components")).containsOnly(project.getMainBranchDto().getUuid(), nonMainBranch.getUuid(), branch1.getUuid());
  237. assertThat(uuidsIn("projects")).containsOnly(project.getProjectDto().getUuid());
  238. assertThat(componentUuidsIn("properties")).containsOnly(branch1.getUuid());
  239. }
  240. @Test
  241. public void close_issues_clean_index_and_file_sources_of_disabled_components_specified_by_uuid_in_configuration() {
  242. RuleDto rule = db.rules().insert();
  243. ProjectData projectData = db.components().insertPublicProject();
  244. ComponentDto mainBranch = projectData.getMainBranchComponent();
  245. db.components().insertSnapshot(mainBranch);
  246. db.components().insertSnapshot(mainBranch);
  247. db.components().insertSnapshot(mainBranch, s -> s.setLast(false));
  248. ComponentDto dir = db.components().insertComponent(newDirectory(mainBranch, "sub").setEnabled(false));
  249. ComponentDto srcFile = db.components().insertComponent(newFileDto(mainBranch, dir).setEnabled(false));
  250. ComponentDto testFile = db.components().insertComponent(newFileDto(mainBranch, dir).setEnabled(false));
  251. ComponentDto enabledFile = db.components().insertComponent(newFileDto(mainBranch, dir).setEnabled(true));
  252. IssueDto openOnFile = db.issues().insert(rule, mainBranch, srcFile, issue -> issue.setStatus("OPEN"));
  253. IssueDto confirmOnFile = db.issues().insert(rule, mainBranch, srcFile, issue -> issue.setStatus("CONFIRM"));
  254. IssueDto openOnDir = db.issues().insert(rule, mainBranch, dir, issue -> issue.setStatus("OPEN"));
  255. IssueDto confirmOnDir = db.issues().insert(rule, mainBranch, dir, issue -> issue.setStatus("CONFIRM"));
  256. IssueDto openOnEnabledComponent = db.issues().insert(rule, mainBranch, enabledFile, issue -> issue.setStatus("OPEN"));
  257. IssueDto confirmOnEnabledComponent = db.issues().insert(rule, mainBranch, enabledFile, issue -> issue.setStatus("CONFIRM"));
  258. assertThat(db.countSql("select count(*) from snapshots where purge_status = 1")).isZero();
  259. assertThat(db.countSql("select count(*) from issues where status = 'CLOSED'")).isZero();
  260. assertThat(db.countSql("select count(*) from issues where resolution = 'REMOVED'")).isZero();
  261. db.fileSources().insertFileSource(srcFile);
  262. FileSourceDto nonSelectedFileSource = db.fileSources().insertFileSource(enabledFile);
  263. assertThat(db.countRowsOfTable("file_sources")).isEqualTo(2);
  264. MetricDto metric1 = db.measures().insertMetric();
  265. MetricDto metric2 = db.measures().insertMetric();
  266. LiveMeasureDto liveMeasureMetric1OnFile = db.measures().insertLiveMeasure(srcFile, metric1);
  267. LiveMeasureDto liveMeasureMetric2OnFile = db.measures().insertLiveMeasure(srcFile, metric2);
  268. LiveMeasureDto liveMeasureMetric1OnDir = db.measures().insertLiveMeasure(dir, metric1);
  269. LiveMeasureDto liveMeasureMetric2OnDir = db.measures().insertLiveMeasure(dir, metric2);
  270. LiveMeasureDto liveMeasureMetric1OnProject = db.measures().insertLiveMeasure(mainBranch, metric1);
  271. LiveMeasureDto liveMeasureMetric2OnProject = db.measures().insertLiveMeasure(mainBranch, metric2);
  272. LiveMeasureDto liveMeasureMetric1OnNonSelected = db.measures().insertLiveMeasure(enabledFile, metric1);
  273. LiveMeasureDto liveMeasureMetric2OnNonSelected = db.measures().insertLiveMeasure(enabledFile, metric2);
  274. assertThat(db.countRowsOfTable("live_measures")).isEqualTo(8);
  275. PurgeListener purgeListener = mock(PurgeListener.class);
  276. // back to present
  277. Set<String> selectedComponentUuids = ImmutableSet.of(srcFile.uuid(), testFile.uuid());
  278. underTest.purge(dbSession, newConfigurationWith30Days(system2, mainBranch.uuid(), projectData.projectUuid(), selectedComponentUuids),
  279. purgeListener, new PurgeProfiler());
  280. dbSession.commit();
  281. // set purge_status=1 for non-last snapshot
  282. assertThat(db.countSql("select count(*) from snapshots where purge_status = 1")).isOne();
  283. // close open issues of selected
  284. assertThat(db.countSql("select count(*) from issues where status = 'CLOSED'")).isEqualTo(4);
  285. for (IssueDto issue : Arrays.asList(openOnFile, confirmOnFile, openOnDir, confirmOnDir)) {
  286. assertThat(db.getDbClient().issueDao().selectOrFailByKey(dbSession, issue.getKey()))
  287. .extracting(IssueDto::getStatus, IssueDto::getResolution)
  288. .containsExactlyInAnyOrder("CLOSED", "REMOVED");
  289. }
  290. for (IssueDto issue : Arrays.asList(openOnEnabledComponent, confirmOnEnabledComponent)) {
  291. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, issue.getKey()).get())
  292. .extracting("status", "resolution")
  293. .containsExactlyInAnyOrder(issue.getStatus(), null);
  294. }
  295. // delete file sources of selected
  296. assertThat(db.countRowsOfTable("file_sources")).isOne();
  297. assertThat(db.getDbClient().fileSourceDao().selectByFileUuid(dbSession, nonSelectedFileSource.getFileUuid())).isNotNull();
  298. // deletes live measure of selected
  299. assertThat(db.countRowsOfTable("live_measures")).isEqualTo(4);
  300. List<LiveMeasureDto> liveMeasureDtos = db.getDbClient().liveMeasureDao()
  301. .selectByComponentUuidsAndMetricUuids(dbSession, ImmutableSet.of(srcFile.uuid(), dir.uuid(), mainBranch.uuid(), enabledFile.uuid()),
  302. ImmutableSet.of(metric1.getUuid(), metric2.getUuid()));
  303. assertThat(liveMeasureDtos)
  304. .extracting(LiveMeasureDto::getComponentUuid)
  305. .containsOnly(enabledFile.uuid(), mainBranch.uuid());
  306. assertThat(liveMeasureDtos)
  307. .extracting(LiveMeasureDto::getMetricUuid)
  308. .containsOnly(metric1.getUuid(), metric2.getUuid());
  309. }
  310. @Test
  311. public void shouldDeleteAnalyses() {
  312. ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
  313. SnapshotDto analysis1 = db.components().insertSnapshot(project);
  314. SnapshotDto analysis2 = db.components().insertSnapshot(project);
  315. SnapshotDto analysis3 = db.components().insertSnapshot(project);
  316. ComponentDto otherProject = db.components().insertPrivateProject().getMainBranchComponent();
  317. SnapshotDto otherAnalysis1 = db.components().insertSnapshot(otherProject);
  318. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), singletonList(analysis1.getUuid()));
  319. assertThat(uuidsIn("snapshots")).containsOnly(analysis2.getUuid(), analysis3.getUuid(), otherAnalysis1.getUuid());
  320. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), asList(analysis1.getUuid(), analysis3.getUuid(), otherAnalysis1.getUuid()));
  321. assertThat(uuidsIn("snapshots")).containsOnly(analysis2.getUuid());
  322. }
  323. @Test
  324. public void purge_should_log_profiling_in_debug() {
  325. ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
  326. logTester.setLevel(Level.DEBUG);
  327. underTest.deleteProject(db.getSession(), project.uuid(), Qualifiers.PROJECT, project.name(), project.getKey());
  328. assertThat(logTester.getLogs(LoggerLevel.DEBUG).stream()
  329. .map(LogAndArguments::getFormattedMsg)
  330. .collect(Collectors.joining()))
  331. .contains("Profiling for project deletion");
  332. }
  333. @Test
  334. public void purge_should_not_log_profiling_in_info() {
  335. ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
  336. logTester.setLevel(Level.INFO);
  337. underTest.deleteProject(db.getSession(), project.uuid(), Qualifiers.PROJECT, project.name(), project.getKey());
  338. assertThat(logTester.getLogs(LoggerLevel.DEBUG).stream()
  339. .map(LogAndArguments::getFormattedMsg)
  340. .collect(Collectors.joining()))
  341. .doesNotContain("Profiling for project deletion");
  342. }
  343. @Test
  344. public void deleteAnalyses_deletes_rows_in_events_and_event_component_changes() {
  345. ComponentDto project = ComponentTesting.newPrivateProjectDto();
  346. dbClient.componentDao().insert(dbSession, project, true);
  347. SnapshotDto projectAnalysis1 = db.components().insertSnapshot(project);
  348. SnapshotDto projectAnalysis2 = db.components().insertSnapshot(project);
  349. SnapshotDto projectAnalysis3 = db.components().insertSnapshot(project);
  350. SnapshotDto projectAnalysis4 = db.components().insertSnapshot(project);
  351. EventDto projectEvent1 = db.events().insertEvent(projectAnalysis1);
  352. EventDto projectEvent2 = db.events().insertEvent(projectAnalysis2);
  353. EventDto projectEvent3 = db.events().insertEvent(projectAnalysis3);
  354. // note: projectAnalysis4 has no event
  355. ComponentDto referencedProjectA = db.components().insertPublicProject().getMainBranchComponent();
  356. ComponentDto referencedProjectB = db.components().insertPublicProject().getMainBranchComponent();
  357. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectA, null);
  358. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectB, null);
  359. BranchDto branchProjectA = newBranchDto(referencedProjectA);
  360. ComponentDto cptBranchProjectA = ComponentTesting.newBranchComponent(referencedProjectA, branchProjectA);
  361. db.events().insertEventComponentChanges(projectEvent2, projectAnalysis2, randomChangeCategory(), cptBranchProjectA, branchProjectA);
  362. // note: projectEvent3 has no component change
  363. // delete non existing analysis has no effect
  364. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), singletonList("foo"));
  365. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  366. .containsOnly(projectAnalysis1.getUuid(), projectAnalysis2.getUuid());
  367. assertThat(db.countRowsOfTable("event_component_changes"))
  368. .isEqualTo(3);
  369. assertThat(uuidsIn("events"))
  370. .containsOnly(projectEvent1.getUuid(), projectEvent2.getUuid(), projectEvent3.getUuid());
  371. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), singletonList(projectAnalysis1.getUuid()));
  372. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  373. .containsOnly(projectAnalysis2.getUuid());
  374. assertThat(db.countRowsOfTable("event_component_changes"))
  375. .isOne();
  376. assertThat(uuidsIn("events"))
  377. .containsOnly(projectEvent2.getUuid(), projectEvent3.getUuid());
  378. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), singletonList(projectAnalysis4.getUuid()));
  379. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  380. .containsOnly(projectAnalysis2.getUuid());
  381. assertThat(db.countRowsOfTable("event_component_changes"))
  382. .isOne();
  383. assertThat(uuidsIn("events"))
  384. .containsOnly(projectEvent2.getUuid(), projectEvent3.getUuid());
  385. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), singletonList(projectAnalysis3.getUuid()));
  386. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  387. .containsOnly(projectAnalysis2.getUuid());
  388. assertThat(db.countRowsOfTable("event_component_changes"))
  389. .isOne();
  390. assertThat(uuidsIn("events"))
  391. .containsOnly(projectEvent2.getUuid());
  392. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), singletonList(projectAnalysis2.getUuid()));
  393. assertThat(db.countRowsOfTable("event_component_changes"))
  394. .isZero();
  395. assertThat(db.countRowsOfTable("events"))
  396. .isZero();
  397. }
  398. @Test
  399. public void selectPurgeableAnalyses() {
  400. SnapshotDto[] analyses = new SnapshotDto[] {
  401. newSnapshot()
  402. .setUuid("u1")
  403. .setRootComponentUuid(PROJECT_UUID)
  404. .setStatus(STATUS_PROCESSED)
  405. .setLast(true),
  406. // not processed -> exclude
  407. newSnapshot()
  408. .setUuid("u2")
  409. .setRootComponentUuid(PROJECT_UUID)
  410. .setStatus(STATUS_UNPROCESSED)
  411. .setLast(false),
  412. // on other resource -> exclude
  413. newSnapshot()
  414. .setUuid("u3")
  415. .setRootComponentUuid("uuid_222")
  416. .setStatus(STATUS_PROCESSED)
  417. .setLast(true),
  418. // without event -> select
  419. newSnapshot()
  420. .setUuid("u4")
  421. .setRootComponentUuid(PROJECT_UUID)
  422. .setStatus(STATUS_PROCESSED)
  423. .setLast(false),
  424. // with event -> select
  425. newSnapshot()
  426. .setUuid("u5")
  427. .setRootComponentUuid(PROJECT_UUID)
  428. .setStatus(STATUS_PROCESSED)
  429. .setLast(false)
  430. .setProjectVersion("V5")
  431. };
  432. db.components().insertSnapshots(analyses);
  433. db.events().insertEvent(EventTesting.newEvent(analyses[4])
  434. .setName("V5")
  435. .setCategory(CATEGORY_VERSION));
  436. List<PurgeableAnalysisDto> purgeableAnalyses = underTest.selectPurgeableAnalyses(PROJECT_UUID, dbSession);
  437. assertThat(purgeableAnalyses).hasSize(3);
  438. assertThat(getById(purgeableAnalyses, "u1").isLast()).isTrue();
  439. assertThat(getById(purgeableAnalyses, "u1").hasEvents()).isFalse();
  440. assertThat(getById(purgeableAnalyses, "u1").getVersion()).isNull();
  441. assertThat(getById(purgeableAnalyses, "u4").isLast()).isFalse();
  442. assertThat(getById(purgeableAnalyses, "u4").hasEvents()).isFalse();
  443. assertThat(getById(purgeableAnalyses, "u4").getVersion()).isNull();
  444. assertThat(getById(purgeableAnalyses, "u5").isLast()).isFalse();
  445. assertThat(getById(purgeableAnalyses, "u5").hasEvents()).isTrue();
  446. assertThat(getById(purgeableAnalyses, "u5").getVersion()).isEqualTo("V5");
  447. }
  448. @Test
  449. public void selectPurgeableAnalyses_does_not_return_the_baseline() {
  450. ComponentDto project1 = db.components().insertPublicProject("master").getMainBranchComponent();
  451. SnapshotDto analysis1 = db.components().insertSnapshot(newSnapshot()
  452. .setRootComponentUuid(project1.uuid())
  453. .setStatus(STATUS_PROCESSED)
  454. .setLast(false));
  455. dbClient.newCodePeriodDao().insert(dbSession,
  456. new NewCodePeriodDto()
  457. .setProjectUuid(project1.uuid())
  458. .setBranchUuid(project1.uuid())
  459. .setType(NewCodePeriodType.SPECIFIC_ANALYSIS)
  460. .setValue(analysis1.getUuid()));
  461. ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent();
  462. SnapshotDto analysis2 = db.components().insertSnapshot(newSnapshot()
  463. .setRootComponentUuid(project2.uuid())
  464. .setStatus(STATUS_PROCESSED)
  465. .setLast(false));
  466. db.components().insertProjectBranch(project2);
  467. assertThat(underTest.selectPurgeableAnalyses(project1.uuid(), dbSession)).isEmpty();
  468. assertThat(underTest.selectPurgeableAnalyses(project2.uuid(), dbSession))
  469. .extracting(PurgeableAnalysisDto::getAnalysisUuid)
  470. .containsOnly(analysis2.getUuid());
  471. }
  472. @Test
  473. public void selectPurgeableAnalyses_does_not_return_the_baseline_of_specific_branch() {
  474. ComponentDto project = db.components().insertPublicProject("master").getMainBranchComponent();
  475. SnapshotDto analysisProject = db.components().insertSnapshot(newSnapshot()
  476. .setRootComponentUuid(project.uuid())
  477. .setStatus(STATUS_PROCESSED)
  478. .setLast(false));
  479. dbClient.newCodePeriodDao().insert(dbSession,
  480. new NewCodePeriodDto()
  481. .setProjectUuid(project.uuid())
  482. .setBranchUuid(project.uuid())
  483. .setType(NewCodePeriodType.SPECIFIC_ANALYSIS)
  484. .setValue(analysisProject.getUuid()));
  485. ComponentDto branch1 = db.components().insertProjectBranch(project);
  486. SnapshotDto analysisBranch1 = db.components().insertSnapshot(newSnapshot()
  487. .setRootComponentUuid(branch1.uuid())
  488. .setStatus(STATUS_PROCESSED)
  489. .setLast(false));
  490. ComponentDto branch2 = db.components().insertProjectBranch(project);
  491. SnapshotDto analysisBranch2 = db.components().insertSnapshot(newSnapshot()
  492. .setRootComponentUuid(branch2.uuid())
  493. .setStatus(STATUS_PROCESSED)
  494. .setLast(false));
  495. dbClient.newCodePeriodDao().insert(dbSession,
  496. new NewCodePeriodDto()
  497. .setProjectUuid(project.uuid())
  498. .setBranchUuid(branch2.uuid())
  499. .setType(NewCodePeriodType.SPECIFIC_ANALYSIS)
  500. .setValue(analysisBranch2.getUuid()));
  501. dbSession.commit();
  502. assertThat(underTest.selectPurgeableAnalyses(project.uuid(), dbSession))
  503. .isEmpty();
  504. assertThat(underTest.selectPurgeableAnalyses(branch1.uuid(), dbSession))
  505. .extracting(PurgeableAnalysisDto::getAnalysisUuid)
  506. .containsOnly(analysisBranch1.getUuid());
  507. assertThat(underTest.selectPurgeableAnalyses(branch2.uuid(), dbSession))
  508. .isEmpty();
  509. }
  510. @Test
  511. public void delete_project_and_associated_data() {
  512. RuleDto rule = db.rules().insert();
  513. ProjectData project = db.components().insertPrivateProject();
  514. ComponentDto directory = db.components().insertComponent(newDirectory(project.getMainBranchComponent(), "a/b"));
  515. ComponentDto file = db.components().insertComponent(newFileDto(directory));
  516. SnapshotDto analysis = db.components().insertSnapshot(project.getProjectDto());
  517. IssueDto issue1 = db.issues().insert(rule, project.getMainBranchComponent(), file);
  518. IssueChangeDto issueChange1 = db.issues().insertChange(issue1);
  519. IssueDto issue2 = db.issues().insert(rule, project.getMainBranchComponent(), file);
  520. FileSourceDto fileSource = db.fileSources().insertFileSource(file);
  521. db.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(issue1));
  522. ProjectData otherProject = db.components().insertPrivateProject();
  523. ComponentDto otherDirectory = db.components().insertComponent(newDirectory(otherProject.getMainBranchComponent(), "a/b"));
  524. ComponentDto otherFile = db.components().insertComponent(newFileDto(otherDirectory));
  525. SnapshotDto otherAnalysis = db.components().insertSnapshot(otherProject.getProjectDto());
  526. IssueDto otherIssue1 = db.issues().insert(rule, otherProject.getMainBranchComponent(), otherFile);
  527. IssueChangeDto otherIssueChange1 = db.issues().insertChange(otherIssue1);
  528. IssueDto otherIssue2 = db.issues().insert(rule, otherProject.getMainBranchComponent(), otherFile);
  529. FileSourceDto otherFileSource = db.fileSources().insertFileSource(otherFile);
  530. db.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(otherIssue1));
  531. ProjectDto projectDto = project.getProjectDto();
  532. underTest.deleteProject(dbSession, projectDto.getUuid(), projectDto.getQualifier(), projectDto.getName(), projectDto.getKey());
  533. dbSession.commit();
  534. assertThat(uuidsIn("components")).containsOnly(otherProject.getMainBranchDto().getUuid(), otherDirectory.uuid(), otherFile.uuid());
  535. assertThat(uuidsIn("projects")).containsOnly(otherProject.getProjectDto().getUuid());
  536. assertThat(uuidsIn("snapshots")).containsOnly(otherAnalysis.getUuid());
  537. assertThat(uuidsIn("issues", "kee")).containsOnly(otherIssue1.getKey(), otherIssue2.getKey());
  538. assertThat(uuidsIn("issue_changes", "kee")).containsOnly(otherIssueChange1.getKey());
  539. assertThat(uuidsIn("new_code_reference_issues", "issue_key")).containsOnly(otherIssue1.getKey());
  540. assertThat(uuidsIn("file_sources", "file_uuid")).containsOnly(otherFileSource.getFileUuid());
  541. }
  542. @Test
  543. public void delete_application() {
  544. MetricDto metric = db.measures().insertMetric();
  545. ProjectData project = db.components().insertPrivateProject();
  546. BranchDto mainBranch = db.getDbClient().branchDao().selectByUuid(db.getSession(), project.getMainBranchDto().getUuid()).get();
  547. RuleDto rule = db.rules().insert();
  548. ProjectData app = db.components().insertPrivateApplication();
  549. BranchDto appBranch = db.components().insertProjectBranch(app.getProjectDto());
  550. ProjectData otherApp = db.components().insertPrivateApplication();
  551. BranchDto otherAppBranch = db.components().insertProjectBranch(otherApp.getProjectDto());
  552. SnapshotDto appAnalysis = db.components().insertSnapshot(app.getProjectDto());
  553. SnapshotDto appBranchAnalysis = db.components().insertSnapshot(appBranch);
  554. SnapshotDto otherAppAnalysis = db.components().insertSnapshot(otherApp.getProjectDto());
  555. SnapshotDto otherAppBranchAnalysis = db.components().insertSnapshot(otherAppBranch);
  556. MeasureDto appMeasure = db.measures().insertMeasure(app.getMainBranchComponent(), appAnalysis, metric);
  557. ComponentDto appBranchComponent = db.components().getComponentDto(appBranch);
  558. MeasureDto appBranchMeasure = db.measures().insertMeasure(appBranchComponent, appBranchAnalysis, metric);
  559. MeasureDto otherAppMeasure = db.measures().insertMeasure(otherApp.getMainBranchComponent(), otherAppAnalysis, metric);
  560. ComponentDto otherAppBranchComponent = db.components().getComponentDto(otherAppBranch);
  561. MeasureDto otherAppBranchMeasure = db.measures().insertMeasure(otherAppBranchComponent, otherAppBranchAnalysis, metric);
  562. db.components().addApplicationProject(app.getProjectDto(), project.getProjectDto());
  563. db.components().addApplicationProject(otherApp.getProjectDto(), project.getProjectDto());
  564. db.components().addProjectBranchToApplicationBranch(dbClient.branchDao().selectByUuid(dbSession, appBranch.getUuid()).get(), mainBranch);
  565. db.components().addProjectBranchToApplicationBranch(dbClient.branchDao().selectByUuid(dbSession, otherAppBranch.getUuid()).get(), mainBranch);
  566. ProjectDto appDto = app.getProjectDto();
  567. underTest.deleteProject(dbSession, appDto.getUuid(), appDto.getQualifier(), appDto.getName(), appDto.getKey());
  568. dbSession.commit();
  569. assertThat(uuidsIn("components")).containsOnly(project.getMainBranchDto().getUuid(), otherApp.getMainBranchDto().getUuid(), otherAppBranch.getUuid());
  570. assertThat(uuidsIn("projects")).containsOnly(project.getProjectDto().getUuid(), otherApp.getProjectDto().getUuid());
  571. assertThat(uuidsIn("snapshots")).containsOnly(otherAppAnalysis.getUuid(), otherAppBranchAnalysis.getUuid());
  572. assertThat(uuidsIn("project_branches")).containsOnly(project.getMainBranchDto().getUuid(), otherApp.getMainBranchDto().getUuid(), otherAppBranch.getUuid());
  573. assertThat(uuidsIn("project_measures")).containsOnly(otherAppMeasure.getUuid(), otherAppBranchMeasure.getUuid());
  574. assertThat(uuidsIn("app_projects", "application_uuid")).containsOnly(otherApp.getProjectDto().getUuid());
  575. assertThat(uuidsIn("app_branch_project_branch", "application_branch_uuid")).containsOnly(otherAppBranch.getUuid());
  576. }
  577. @Test
  578. public void delete_application_branch() {
  579. MetricDto metric = db.measures().insertMetric();
  580. ProjectData project = db.components().insertPrivateProject();
  581. BranchDto projectBranch = db.getDbClient().branchDao().selectByUuid(db.getSession(), project.getMainBranchDto().getUuid()).get();
  582. RuleDto rule = db.rules().insert();
  583. ProjectData app = db.components().insertPrivateApplication();
  584. BranchDto appBranch = db.components().insertProjectBranch(app.getProjectDto());
  585. ProjectData otherApp = db.components().insertPrivateApplication();
  586. BranchDto otherAppBranch = db.components().insertProjectBranch(otherApp.getProjectDto());
  587. SnapshotDto appAnalysis = db.components().insertSnapshot(app.getProjectDto());
  588. SnapshotDto appBranchAnalysis = db.components().insertSnapshot(appBranch);
  589. SnapshotDto otherAppAnalysis = db.components().insertSnapshot(otherApp.getProjectDto());
  590. SnapshotDto otherAppBranchAnalysis = db.components().insertSnapshot(otherAppBranch);
  591. MeasureDto appMeasure = db.measures().insertMeasure(app.getMainBranchComponent(), appAnalysis, metric);
  592. ComponentDto appBranchComponent = db.components().getComponentDto(appBranch);
  593. MeasureDto appBranchMeasure = db.measures().insertMeasure(appBranchComponent, appBranchAnalysis, metric);
  594. MeasureDto otherAppMeasure = db.measures().insertMeasure(otherApp.getMainBranchComponent(), otherAppAnalysis, metric);
  595. ComponentDto otherAppBranchComponent = db.components().getComponentDto(otherAppBranch);
  596. MeasureDto otherAppBranchMeasure = db.measures().insertMeasure(otherAppBranchComponent, otherAppBranchAnalysis, metric);
  597. db.components().addApplicationProject(app.getProjectDto(), project.getProjectDto());
  598. db.components().addApplicationProject(otherApp.getProjectDto(), project.getProjectDto());
  599. db.components().addProjectBranchToApplicationBranch(dbClient.branchDao().selectByUuid(dbSession, appBranch.getUuid()).get(), projectBranch);
  600. db.components().addProjectBranchToApplicationBranch(dbClient.branchDao().selectByUuid(dbSession, otherAppBranch.getUuid()).get(), projectBranch);
  601. // properties exist or active and for inactive branch
  602. insertPropertyFor(appBranchComponent, otherAppBranchComponent);
  603. insertReportScheduleAndSubscriptionForBranch(appBranch.getUuid(), dbSession);
  604. underTest.deleteBranch(dbSession, appBranch.getUuid());
  605. dbSession.commit();
  606. assertThat(uuidsIn("components")).containsOnly(project.getMainBranchDto().getUuid(), app.getMainBranchDto().getUuid(), otherApp.getMainBranchDto().getUuid(), otherAppBranch.getUuid());
  607. assertThat(uuidsIn("projects")).containsOnly(project.getProjectDto().getUuid(), app.getProjectDto().getUuid(), otherApp.getProjectDto().getUuid());
  608. assertThat(uuidsIn("snapshots")).containsOnly(otherAppAnalysis.getUuid(), appAnalysis.getUuid(), otherAppBranchAnalysis.getUuid());
  609. assertThat(uuidsIn("project_branches")).containsOnly(project.getMainBranchDto().getUuid(), app.getMainBranchDto().getUuid(), otherApp.getMainBranchDto().getUuid(), otherAppBranch.getUuid());
  610. assertThat(uuidsIn("project_measures")).containsOnly(appMeasure.getUuid(), otherAppMeasure.getUuid(), otherAppBranchMeasure.getUuid());
  611. assertThat(uuidsIn("app_projects", "application_uuid")).containsOnly(app.getProjectDto().getUuid(), otherApp.getProjectDto().getUuid());
  612. assertThat(uuidsIn("app_branch_project_branch", "application_branch_uuid")).containsOnly(otherAppBranch.getUuid());
  613. assertThat(componentUuidsIn("properties")).containsOnly(otherAppBranch.getUuid());
  614. assertThat(uuidsIn("report_schedules", "branch_uuid")).isEmpty();
  615. assertThat(uuidsIn("report_subscriptions", "branch_uuid")).isEmpty();
  616. }
  617. private void insertReportScheduleAndSubscriptionForBranch(String branchUuid, DbSession dbSession) {
  618. db.getDbClient().reportSubscriptionDao().insert(dbSession, new ReportSubscriptionDto().setUuid("uuid")
  619. .setUserUuid("userUuid")
  620. .setBranchUuid(branchUuid));
  621. db.getDbClient().reportScheduleDao().upsert(dbSession, new ReportScheduleDto().setUuid("uuid")
  622. .setBranchUuid(branchUuid)
  623. .setLastSendTimeInMs(2));
  624. }
  625. private void insertReportScheduleAndSubscriptionForPortfolio(String uuid, String portfolioUuid, DbSession dbSession) {
  626. db.getDbClient().reportSubscriptionDao().insert(dbSession, new ReportSubscriptionDto().setUuid(uuid)
  627. .setUserUuid("userUuid")
  628. .setPortfolioUuid(portfolioUuid));
  629. db.getDbClient().reportScheduleDao().upsert(dbSession, new ReportScheduleDto().setUuid(uuid)
  630. .setPortfolioUuid(portfolioUuid)
  631. .setLastSendTimeInMs(2));
  632. }
  633. @Test
  634. public void delete_webhooks_from_project() {
  635. ProjectDto project1 = db.components().insertPrivateProject().getProjectDto();
  636. WebhookDto webhook = db.webhooks().insertWebhook(project1);
  637. db.webhookDelivery().insert(webhook);
  638. ProjectDto projectNotToBeDeleted = db.components().insertPrivateProject().getProjectDto();
  639. WebhookDto webhookNotDeleted = db.webhooks().insertWebhook(projectNotToBeDeleted);
  640. WebhookDeliveryLiteDto webhookDeliveryNotDeleted = db.webhookDelivery().insert(webhookNotDeleted);
  641. underTest.deleteProject(dbSession, project1.getUuid(), project1.getQualifier(), project1.getName(), project1.getKey());
  642. assertThat(uuidsIn("webhooks")).containsOnly(webhookNotDeleted.getUuid());
  643. assertThat(uuidsIn("webhook_deliveries")).containsOnly(webhookDeliveryNotDeleted.getUuid());
  644. }
  645. private Stream<String> uuidsOfTable(String tableName) {
  646. return db.select("select uuid as \"UUID\" from " + tableName)
  647. .stream()
  648. .map(s -> (String) s.get("UUID"));
  649. }
  650. @Test
  651. public void delete_row_in_ce_activity_when_deleting_project() {
  652. ComponentDto projectToBeDeleted = ComponentTesting.newPrivateProjectDto();
  653. ComponentDto anotherLivingProject = ComponentTesting.newPrivateProjectDto();
  654. insertComponents(List.of(anotherLivingProject), List.of(projectToBeDeleted));
  655. // Insert 2 rows in CE_ACTIVITY : one for the project that will be deleted, and one on another project
  656. CeActivityDto toBeDeletedActivity = insertCeActivity(projectToBeDeleted, projectToBeDeleted.uuid());
  657. CeActivityDto notDeletedActivity = insertCeActivity(anotherLivingProject, anotherLivingProject.uuid());
  658. dbSession.commit();
  659. underTest.deleteProject(dbSession, projectToBeDeleted.uuid(), projectToBeDeleted.qualifier(), projectToBeDeleted.name(), projectToBeDeleted.getKey());
  660. dbSession.commit();
  661. assertThat(uuidsOfTable("ce_activity"))
  662. .containsOnly(notDeletedActivity.getUuid())
  663. .hasSize(1);
  664. }
  665. @Test
  666. public void delete_row_in_ce_task_input_referring_to_a_row_in_ce_activity_when_deleting_project() {
  667. ProjectData project = db.components().insertPrivateProject();
  668. ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent());
  669. ComponentDto anotherBranch = db.components().insertProjectBranch(project.getMainBranchComponent());
  670. ProjectData anotherProject = db.components().insertPrivateProject();
  671. CeActivityDto projectTask = insertCeActivity(project.getMainBranchComponent(), project.getProjectDto().getUuid());
  672. insertCeTaskInput(projectTask.getUuid());
  673. CeActivityDto branchTask = insertCeActivity(branch, project.getProjectDto().getUuid());
  674. insertCeTaskInput(branchTask.getUuid());
  675. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch, project.getProjectDto().getUuid());
  676. insertCeTaskInput(anotherBranchTask.getUuid());
  677. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject.getMainBranchComponent(), anotherProject.getProjectDto().getUuid());
  678. insertCeTaskInput(anotherProjectTask.getUuid());
  679. insertCeTaskInput("non existing task");
  680. dbSession.commit();
  681. underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.getProjectDto().getName(), project.getProjectDto().getKey());
  682. dbSession.commit();
  683. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  684. assertThat(taskUuidsIn("ce_task_input")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  685. underTest.deleteProject(dbSession, project.getProjectDto().getUuid(), project.getProjectDto().getQualifier(), project.getProjectDto().getName(), project.getProjectDto().getKey());
  686. dbSession.commit();
  687. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  688. assertThat(taskUuidsIn("ce_task_input")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  689. }
  690. @Test
  691. public void delete_row_in_ce_scanner_context_referring_to_a_row_in_ce_activity_when_deleting_project() {
  692. ProjectData project = db.components().insertPrivateProject();
  693. ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent());
  694. ComponentDto anotherBranch = db.components().insertProjectBranch(project.getMainBranchComponent());
  695. ProjectData anotherProject = db.components().insertPrivateProject();
  696. CeActivityDto projectTask = insertCeActivity(project.getMainBranchComponent(), project.getProjectDto().getUuid());
  697. insertCeScannerContext(projectTask.getUuid());
  698. CeActivityDto branchTask = insertCeActivity(branch, project.getProjectDto().getUuid());
  699. insertCeScannerContext(branchTask.getUuid());
  700. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch, project.getProjectDto().getUuid());
  701. insertCeScannerContext(anotherBranchTask.getUuid());
  702. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject.getMainBranchComponent(), anotherProject.getProjectDto().getUuid());
  703. insertCeScannerContext(anotherProjectTask.getUuid());
  704. insertCeScannerContext("non existing task");
  705. dbSession.commit();
  706. underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.getProjectDto().getName(), project.getProjectDto().getKey());
  707. dbSession.commit();
  708. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  709. assertThat(taskUuidsIn("ce_scanner_context")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  710. underTest.deleteProject(dbSession, project.getProjectDto().getUuid(), project.getProjectDto().getQualifier(), project.getProjectDto().getName(), project.getProjectDto().getKey());
  711. dbSession.commit();
  712. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  713. assertThat(taskUuidsIn("ce_scanner_context")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  714. }
  715. @Test
  716. public void delete_row_in_ce_task_characteristics_referring_to_a_row_in_ce_activity_when_deleting_project() {
  717. ProjectData project = db.components().insertPrivateProject();
  718. ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent());
  719. ComponentDto anotherBranch = db.components().insertProjectBranch(project.getMainBranchComponent());
  720. ProjectData anotherProject = db.components().insertPrivateProject();
  721. CeActivityDto projectTask = insertCeActivity(project.getMainBranchComponent(), project.projectUuid());
  722. insertCeTaskCharacteristics(projectTask.getUuid(), 3);
  723. CeActivityDto branchTask = insertCeActivity(branch, project.projectUuid());
  724. insertCeTaskCharacteristics(branchTask.getUuid(), 2);
  725. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch, project.projectUuid());
  726. insertCeTaskCharacteristics(anotherBranchTask.getUuid(), 6);
  727. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject.getMainBranchComponent(), anotherProject.projectUuid());
  728. insertCeTaskCharacteristics(anotherProjectTask.getUuid(), 2);
  729. insertCeTaskCharacteristics("non existing task", 5);
  730. dbSession.commit();
  731. underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.getProjectDto().getName(), project.getProjectDto().getKey());
  732. dbSession.commit();
  733. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  734. assertThat(taskUuidsIn("ce_task_characteristics")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  735. underTest.deleteProject(dbSession, project.getProjectDto().getUuid(), project.getProjectDto().getQualifier(), project.getProjectDto().getName(), project.getProjectDto().getKey());
  736. dbSession.commit();
  737. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  738. assertThat(taskUuidsIn("ce_task_characteristics")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  739. }
  740. @Test
  741. public void delete_row_in_ce_task_message_referring_to_a_row_in_ce_activity_when_deleting_project() {
  742. ProjectData project = db.components().insertPrivateProject();
  743. ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent());
  744. ComponentDto anotherBranch = db.components().insertProjectBranch(project.getMainBranchComponent());
  745. ProjectData anotherProject = db.components().insertPrivateProject();
  746. CeActivityDto projectTask = insertCeActivity(project.getMainBranchComponent(), project.getProjectDto().getUuid());
  747. insertCeTaskMessages(projectTask.getUuid(), 3);
  748. CeActivityDto branchTask = insertCeActivity(branch, project.getProjectDto().getUuid());
  749. insertCeTaskMessages(branchTask.getUuid(), 2);
  750. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch, project.getProjectDto().getUuid());
  751. insertCeTaskMessages(anotherBranchTask.getUuid(), 6);
  752. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject.getMainBranchComponent(), anotherProject.getProjectDto().getUuid());
  753. insertCeTaskMessages(anotherProjectTask.getUuid(), 2);
  754. insertCeTaskMessages("non existing task", 5);
  755. dbSession.commit();
  756. underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.getProjectDto().getName(), project.getProjectDto().getKey());
  757. dbSession.commit();
  758. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  759. assertThat(taskUuidsIn("ce_task_message")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  760. underTest.deleteProject(dbSession, project.getProjectDto().getUuid(), project.getProjectDto().getQualifier(), project.getProjectDto().getName(), project.getProjectDto().getKey());
  761. dbSession.commit();
  762. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  763. assertThat(taskUuidsIn("ce_task_message")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  764. }
  765. @Test
  766. public void delete_rows_in_user_dismissed_messages_when_deleting_project() {
  767. UserDto user1 = db.users().insertUser();
  768. UserDto user2 = db.users().insertUser();
  769. ProjectDto project = db.components().insertPrivateProject().getProjectDto();
  770. ProjectDto anotherProject = db.components().insertPrivateProject().getProjectDto();
  771. UserDismissedMessageDto msg1 = db.users().insertUserDismissedMessage(user1, project, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE);
  772. UserDismissedMessageDto msg2 = db.users().insertUserDismissedMessage(user2, project, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE);
  773. UserDismissedMessageDto msg3 = db.users().insertUserDismissedMessage(user1, anotherProject, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE);
  774. assertThat(uuidsIn("user_dismissed_messages")).containsOnly(msg1.getUuid(), msg2.getUuid(), msg3.getUuid());
  775. underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier(), project.getName(), project.getKey());
  776. dbSession.commit();
  777. assertThat(uuidsIn("user_dismissed_messages")).containsOnly(msg3.getUuid());
  778. }
  779. @Test
  780. public void delete_tasks_in_ce_queue_when_deleting_project() {
  781. ProjectData projectToBeDeleted = db.components().insertPrivateProject();
  782. ProjectData anotherLivingProject = db.components().insertPrivateProject();
  783. // Insert 3 rows in CE_QUEUE: two for the project that will be deleted (in order to check that status
  784. // is not involved in deletion), and one on another project
  785. dbClient.ceQueueDao().insert(dbSession, createCeQueue(projectToBeDeleted.getMainBranchComponent(), projectToBeDeleted.projectUuid(), Status.PENDING));
  786. dbClient.ceQueueDao().insert(dbSession, createCeQueue(projectToBeDeleted.getMainBranchComponent(), projectToBeDeleted.projectUuid(), Status.IN_PROGRESS));
  787. dbClient.ceQueueDao().insert(dbSession, createCeQueue(anotherLivingProject.getMainBranchComponent(), anotherLivingProject.projectUuid(), Status.PENDING));
  788. dbSession.commit();
  789. ProjectDto projectDto = projectToBeDeleted.getProjectDto();
  790. underTest.deleteProject(dbSession, projectDto.getUuid(),
  791. projectDto.getQualifier(), projectDto.getName(), projectDto.getKey());
  792. dbSession.commit();
  793. assertThat(db.countRowsOfTable("ce_queue")).isOne();
  794. assertThat(db.countSql("select count(*) from ce_queue where entity_uuid='" + projectToBeDeleted.projectUuid() + "'")).isZero();
  795. }
  796. @Test
  797. public void delete_row_in_ce_task_input_referring_to_a_row_in_ce_queue_when_deleting_project() {
  798. ComponentDto project = ComponentTesting.newPrivateProjectDto();
  799. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  800. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  801. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto();
  802. insertComponents(List.of(project, anotherProject), List.of(branch, anotherBranch));
  803. CeQueueDto projectTask = insertCeQueue(project);
  804. insertCeTaskInput(projectTask.getUuid());
  805. CeQueueDto branchTask = insertCeQueue(branch, project.uuid());
  806. insertCeTaskInput(branchTask.getUuid());
  807. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch, project.uuid());
  808. insertCeTaskInput(anotherBranchTask.getUuid());
  809. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  810. insertCeTaskInput(anotherProjectTask.getUuid());
  811. insertCeTaskInput("non existing task");
  812. dbSession.commit();
  813. underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey());
  814. dbSession.commit();
  815. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  816. assertThat(taskUuidsIn("ce_task_input")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  817. underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey());
  818. dbSession.commit();
  819. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  820. assertThat(taskUuidsIn("ce_task_input")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  821. }
  822. @Test
  823. public void delete_row_in_ce_scanner_context_referring_to_a_row_in_ce_queue_when_deleting_project() {
  824. ComponentDto project = ComponentTesting.newPrivateProjectDto();
  825. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  826. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  827. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto();
  828. insertComponents(List.of(project, anotherProject), List.of(branch, anotherBranch));
  829. CeQueueDto projectTask = insertCeQueue(project);
  830. insertCeScannerContext(projectTask.getUuid());
  831. CeQueueDto branchTask = insertCeQueue(branch, project.uuid());
  832. insertCeScannerContext(branchTask.getUuid());
  833. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch, project.uuid());
  834. insertCeScannerContext(anotherBranchTask.getUuid());
  835. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  836. insertCeScannerContext(anotherProjectTask.getUuid());
  837. insertCeScannerContext("non existing task");
  838. dbSession.commit();
  839. underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey());
  840. dbSession.commit();
  841. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  842. assertThat(taskUuidsIn("ce_scanner_context"))
  843. .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  844. underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey());
  845. dbSession.commit();
  846. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  847. assertThat(taskUuidsIn("ce_scanner_context")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  848. }
  849. private void insertComponents(List<ComponentDto> componentsOnMainBranch, List<ComponentDto> componentsNotOnMainBranch) {
  850. componentsOnMainBranch.forEach(c -> dbClient.componentDao().insert(dbSession, c, true));
  851. componentsNotOnMainBranch.forEach(c -> dbClient.componentDao().insert(dbSession, c, false));
  852. }
  853. @Test
  854. public void delete_row_in_ce_task_characteristics_referring_to_a_row_in_ce_queue_when_deleting_project() {
  855. ComponentDto project = ComponentTesting.newPrivateProjectDto();
  856. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  857. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  858. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto();
  859. insertComponents(List.of(project, anotherProject), List.of(branch, anotherBranch));
  860. CeQueueDto projectTask = insertCeQueue(project);
  861. insertCeTaskCharacteristics(projectTask.getUuid(), 3);
  862. CeQueueDto branchTask = insertCeQueue(branch, project.uuid());
  863. insertCeTaskCharacteristics(branchTask.getUuid(), 1);
  864. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch, project.uuid());
  865. insertCeTaskCharacteristics(anotherBranchTask.getUuid(), 5);
  866. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  867. insertCeTaskCharacteristics(anotherProjectTask.getUuid(), 2);
  868. insertCeTaskCharacteristics("non existing task", 5);
  869. dbSession.commit();
  870. underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey());
  871. dbSession.commit();
  872. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  873. assertThat(taskUuidsIn("ce_task_characteristics"))
  874. .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  875. underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey());
  876. dbSession.commit();
  877. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  878. assertThat(taskUuidsIn("ce_task_characteristics")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  879. }
  880. @Test
  881. public void delete_row_in_ce_task_message_referring_to_a_row_in_ce_queue_when_deleting_project() {
  882. ComponentDto project = ComponentTesting.newPrivateProjectDto();
  883. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  884. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  885. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto();
  886. insertComponents(List.of(project, anotherProject), List.of(branch, anotherBranch));
  887. CeQueueDto projectTask = insertCeQueue(project);
  888. insertCeTaskMessages(projectTask.getUuid(), 3);
  889. CeQueueDto branchTask = insertCeQueue(branch, project.uuid());
  890. insertCeTaskMessages(branchTask.getUuid(), 1);
  891. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch, project.uuid());
  892. insertCeTaskMessages(anotherBranchTask.getUuid(), 5);
  893. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  894. insertCeTaskMessages(anotherProjectTask.getUuid(), 2);
  895. insertCeTaskMessages("non existing task", 5);
  896. dbSession.commit();
  897. underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey());
  898. dbSession.commit();
  899. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  900. assertThat(taskUuidsIn("ce_task_message"))
  901. .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  902. underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey());
  903. dbSession.commit();
  904. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  905. assertThat(taskUuidsIn("ce_task_message")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  906. }
  907. @Test
  908. public void delete_row_in_events_and_event_component_changes_when_deleting_project() {
  909. ComponentDto project = ComponentTesting.newPrivateProjectDto();
  910. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  911. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  912. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto();
  913. insertComponents(List.of(project, anotherProject), List.of(branch, anotherBranch));
  914. SnapshotDto projectAnalysis1 = db.components().insertSnapshot(project);
  915. SnapshotDto projectAnalysis2 = db.components().insertSnapshot(project);
  916. EventDto projectEvent1 = db.events().insertEvent(projectAnalysis1);
  917. EventDto projectEvent2 = db.events().insertEvent(projectAnalysis2);
  918. EventDto projectEvent3 = db.events().insertEvent(db.components().insertSnapshot(project));
  919. SnapshotDto branchAnalysis1 = db.components().insertSnapshot(branch);
  920. SnapshotDto branchAnalysis2 = db.components().insertSnapshot(branch);
  921. EventDto branchEvent1 = db.events().insertEvent(branchAnalysis1);
  922. EventDto branchEvent2 = db.events().insertEvent(branchAnalysis2);
  923. SnapshotDto anotherBranchAnalysis = db.components().insertSnapshot(anotherBranch);
  924. EventDto anotherBranchEvent = db.events().insertEvent(anotherBranchAnalysis);
  925. SnapshotDto anotherProjectAnalysis = db.components().insertSnapshot(anotherProject);
  926. EventDto anotherProjectEvent = db.events().insertEvent(anotherProjectAnalysis);
  927. ComponentDto referencedProjectA = db.components().insertPublicProject().getMainBranchComponent();
  928. ComponentDto referencedProjectB = db.components().insertPublicProject().getMainBranchComponent();
  929. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectA, null);
  930. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectB, null);
  931. BranchDto branchProjectA = newBranchDto(referencedProjectA);
  932. ComponentDto cptBranchProjectA = ComponentTesting.newBranchComponent(referencedProjectA, branchProjectA);
  933. db.events().insertEventComponentChanges(projectEvent2, projectAnalysis2, randomChangeCategory(), cptBranchProjectA, branchProjectA);
  934. // note: projectEvent3 has no component change
  935. db.events().insertEventComponentChanges(branchEvent1, branchAnalysis1, randomChangeCategory(), referencedProjectB, null);
  936. db.events().insertEventComponentChanges(branchEvent2, branchAnalysis2, randomChangeCategory(), cptBranchProjectA, branchProjectA);
  937. db.events().insertEventComponentChanges(anotherBranchEvent, anotherBranchAnalysis, randomChangeCategory(), referencedProjectB, null);
  938. db.events().insertEventComponentChanges(anotherProjectEvent, anotherProjectAnalysis, randomChangeCategory(), referencedProjectB, null);
  939. // deleting referenced project does not delete any data
  940. underTest.deleteProject(dbSession, referencedProjectA.uuid(), referencedProjectA.qualifier(), project.name(), project.getKey());
  941. assertThat(db.countRowsOfTable("event_component_changes"))
  942. .isEqualTo(7);
  943. assertThat(db.countRowsOfTable("events"))
  944. .isEqualTo(7);
  945. underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey());
  946. assertThat(uuidsIn("event_component_changes", "event_component_uuid"))
  947. .containsOnly(project.uuid(), anotherBranch.uuid(), anotherProject.uuid());
  948. assertThat(db.countRowsOfTable("event_component_changes"))
  949. .isEqualTo(5);
  950. assertThat(uuidsIn("events"))
  951. .containsOnly(projectEvent1.getUuid(), projectEvent2.getUuid(), projectEvent3.getUuid(), anotherBranchEvent.getUuid(), anotherProjectEvent.getUuid());
  952. underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey());
  953. assertThat(uuidsIn("event_component_changes", "event_component_uuid"))
  954. .containsOnly(anotherBranch.uuid(), anotherProject.uuid());
  955. assertThat(db.countRowsOfTable("event_component_changes"))
  956. .isEqualTo(2);
  957. assertThat(uuidsIn("events"))
  958. .containsOnly(anotherBranchEvent.getUuid(), anotherProjectEvent.getUuid());
  959. }
  960. private static EventComponentChangeDto.ChangeCategory randomChangeCategory() {
  961. return EventComponentChangeDto.ChangeCategory.values()[new Random().nextInt(EventComponentChangeDto.ChangeCategory.values().length)];
  962. }
  963. private ProjectDto insertProjectWithBranchAndRelatedData() {
  964. RuleDto rule = db.rules().insert();
  965. ProjectData project = db.components().insertPublicProject();
  966. BranchDto branch = db.components().insertProjectBranch(project.getProjectDto());
  967. ComponentDto branchComponent = db.components().getComponentDto(branch);
  968. ComponentDto dir = db.components().insertComponent(newDirectory(branchComponent, "path"));
  969. ComponentDto file = db.components().insertComponent(newFileDto(branchComponent, dir));
  970. db.issues().insert(rule, branchComponent, file);
  971. db.issues().insert(rule, branchComponent, dir);
  972. return project.getProjectDto();
  973. }
  974. @Test
  975. public void delete_branch_content_when_deleting_project() {
  976. ProjectDto anotherLivingProject = insertProjectWithBranchAndRelatedData();
  977. int projectEntryCount = db.countRowsOfTable("components");
  978. int issueCount = db.countRowsOfTable("issues");
  979. int branchCount = db.countRowsOfTable("project_branches");
  980. Collection<BranchDto> anotherLivingProjectBranches = db.getDbClient().branchDao()
  981. .selectByProject(db.getSession(), anotherLivingProject);
  982. insertPropertyFor(anotherLivingProjectBranches);
  983. assertThat(db.countRowsOfTable("properties")).isEqualTo(anotherLivingProjectBranches.size());
  984. ProjectDto projectToDelete = insertProjectWithBranchAndRelatedData();
  985. Collection<BranchDto> projectToDeleteBranches = db.getDbClient().branchDao()
  986. .selectByProject(db.getSession(), projectToDelete);
  987. insertPropertyFor(projectToDeleteBranches);
  988. assertThat(db.countRowsOfTable("properties")).isEqualTo(anotherLivingProjectBranches.size() + projectToDeleteBranches.size());
  989. assertThat(db.countRowsOfTable("components")).isGreaterThan(projectEntryCount);
  990. assertThat(db.countRowsOfTable("issues")).isGreaterThan(issueCount);
  991. assertThat(db.countRowsOfTable("project_branches")).isGreaterThan(branchCount);
  992. underTest.deleteProject(dbSession, projectToDelete.getUuid(), projectToDelete.getQualifier(), projectToDelete.getName(), projectToDelete.getKey());
  993. dbSession.commit();
  994. assertThat(db.countRowsOfTable("components")).isEqualTo(projectEntryCount);
  995. assertThat(db.countRowsOfTable("issues")).isEqualTo(issueCount);
  996. assertThat(db.countRowsOfTable("project_branches")).isEqualTo(branchCount);
  997. assertThat(db.countRowsOfTable("properties")).isEqualTo(anotherLivingProjectBranches.size());
  998. }
  999. @Test
  1000. public void delete_view_and_child() {
  1001. ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
  1002. ComponentDto view = db.components().insertPrivatePortfolio();
  1003. ComponentDto subView = db.components().insertComponent(newSubPortfolio(view));
  1004. ComponentDto projectCopy = db.components().insertComponent(newProjectCopy(project, subView));
  1005. ComponentDto otherView = db.components().insertPrivatePortfolio();
  1006. ComponentDto otherSubView = db.components().insertComponent(newSubPortfolio(otherView));
  1007. ComponentDto otherProjectCopy = db.components().insertComponent(newProjectCopy(project, otherSubView));
  1008. underTest.deleteProject(dbSession, view.uuid(), view.qualifier(), project.name(), project.getKey());
  1009. dbSession.commit();
  1010. assertThat(uuidsIn("components"))
  1011. .containsOnly(project.uuid(), otherView.uuid(), otherSubView.uuid(), otherProjectCopy.uuid());
  1012. }
  1013. @Test
  1014. public void purge_shouldDeleteOrphanIssues() {
  1015. RuleDto rule = db.rules().insert();
  1016. ProjectData projectData = db.components().insertPublicProject();
  1017. ComponentDto mainBranch = projectData.getMainBranchComponent();
  1018. ComponentDto otherProject = db.components().insertPublicProject().getMainBranchComponent();
  1019. ComponentDto dir = db.components().insertComponent(newDirectory(mainBranch, "path"));
  1020. ComponentDto file = db.components().insertComponent(newFileDto(mainBranch, dir));
  1021. IssueDto issue1 = db.issues().insert(rule, mainBranch, file);
  1022. IssueDto orphanIssue = db.issues().insert(rule, mainBranch, file, issue -> issue.setComponentUuid("nonExisting"));
  1023. IssueChangeDto orphanIssueChange = db.issues().insertChange(orphanIssue);
  1024. db.issues().insertNewCodeReferenceIssue(orphanIssue);
  1025. underTest.purge(dbSession, newConfigurationWith30Days(system2, mainBranch.uuid(), projectData.projectUuid()), PurgeListener.EMPTY, new PurgeProfiler());
  1026. db.commit();
  1027. assertThat(db.countRowsOfTable("issue_changes")).isZero();
  1028. assertThat(db.countRowsOfTable("new_code_reference_issues")).isZero();
  1029. assertThat(db.select("select kee as \"KEE\" from issues")).extracting(i -> i.get("KEE")).containsOnly(issue1.getKey());
  1030. }
  1031. @Test
  1032. public void should_delete_old_closed_issues() {
  1033. RuleDto rule = db.rules().insert();
  1034. ProjectData projectData = db.components().insertPublicProject();
  1035. ComponentDto mainBranch = projectData.getMainBranchComponent();
  1036. ComponentDto dir = db.components().insertComponent(newDirectory(mainBranch, "path"));
  1037. ComponentDto file = db.components().insertComponent(newFileDto(mainBranch, dir));
  1038. IssueDto oldClosed = db.issues().insert(rule, mainBranch, file, issue -> {
  1039. issue.setStatus("CLOSED");
  1040. issue.setIssueCloseDate(DateUtils.addDays(new Date(), -31));
  1041. });
  1042. db.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(oldClosed));
  1043. IssueDto notOldEnoughClosed = db.issues().insert(rule, mainBranch, file, issue -> {
  1044. issue.setStatus("CLOSED");
  1045. issue.setIssueCloseDate(new Date());
  1046. });
  1047. db.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(notOldEnoughClosed));
  1048. IssueDto notClosed = db.issues().insert(rule, mainBranch, file);
  1049. db.issues().insertNewCodeReferenceIssue(newCodeReferenceIssue(notClosed));
  1050. when(system2.now()).thenReturn(new Date().getTime());
  1051. underTest.purge(dbSession, newConfigurationWith30Days(system2, mainBranch.uuid(), projectData.projectUuid()), PurgeListener.EMPTY, new PurgeProfiler());
  1052. dbSession.commit();
  1053. // old closed got deleted
  1054. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, oldClosed.getKey())).isEmpty();
  1055. // others remain
  1056. assertThat(db.countRowsOfTable("issues")).isEqualTo(2);
  1057. Optional<IssueDto> notOldEnoughClosedFromQuery = db.getDbClient().issueDao().selectByKey(dbSession, notOldEnoughClosed.getKey());
  1058. assertThat(notOldEnoughClosedFromQuery).isNotEmpty();
  1059. assertThat(notOldEnoughClosedFromQuery.get().isNewCodeReferenceIssue()).isTrue();
  1060. Optional<IssueDto> notClosedFromQuery = db.getDbClient().issueDao().selectByKey(dbSession, notClosed.getKey());
  1061. assertThat(notClosedFromQuery).isNotEmpty();
  1062. assertThat(notClosedFromQuery.get().isNewCodeReferenceIssue()).isTrue();
  1063. Optional<IssueDto> oldClosedFromQuery = db.getDbClient().issueDao().selectByKey(dbSession, oldClosed.getKey());
  1064. assertThat(oldClosedFromQuery).isEmpty();
  1065. }
  1066. @Test
  1067. public void delete_disabled_components_without_issues() {
  1068. ProjectData projectData = db.components().insertPublicProject(p -> p.setEnabled(true));
  1069. ComponentDto mainBranch = projectData.getMainBranchComponent();
  1070. ComponentDto enabledFileWithIssues = db.components().insertComponent(newFileDto(mainBranch).setEnabled(true));
  1071. ComponentDto disabledFileWithIssues = db.components().insertComponent(newFileDto(mainBranch).setEnabled(false));
  1072. ComponentDto enabledFileWithoutIssues = db.components().insertComponent(newFileDto(mainBranch).setEnabled(true));
  1073. ComponentDto disabledFileWithoutIssues = db.components().insertComponent(newFileDto(mainBranch).setEnabled(false));
  1074. RuleDto rule = db.rules().insert();
  1075. IssueDto closed1 = db.issues().insert(rule, mainBranch, enabledFileWithIssues, issue -> {
  1076. issue.setStatus("CLOSED");
  1077. issue.setResolution(Issue.RESOLUTION_FIXED);
  1078. issue.setIssueCloseDate(new Date());
  1079. });
  1080. IssueDto closed2 = db.issues().insert(rule, mainBranch, disabledFileWithIssues, issue -> {
  1081. issue.setStatus("CLOSED");
  1082. issue.setResolution(Issue.RESOLUTION_FIXED);
  1083. issue.setIssueCloseDate(new Date());
  1084. });
  1085. PurgeListener purgeListener = mock(PurgeListener.class);
  1086. Set<String> disabledComponentUuids = ImmutableSet.of(disabledFileWithIssues.uuid(), disabledFileWithoutIssues.uuid());
  1087. underTest.purge(dbSession,
  1088. newConfigurationWith30Days(System2.INSTANCE, mainBranch.uuid(), projectData.projectUuid(), disabledComponentUuids),
  1089. purgeListener, new PurgeProfiler());
  1090. assertThat(db.getDbClient().componentDao().selectByBranchUuid(mainBranch.uuid(), dbSession))
  1091. .extracting("uuid")
  1092. .containsOnly(mainBranch.uuid(), enabledFileWithIssues.uuid(), disabledFileWithIssues.uuid(),
  1093. enabledFileWithoutIssues.uuid());
  1094. }
  1095. @Test
  1096. public void delete_ce_analysis_older_than_180_and_scanner_context_older_than_40_days_of_specified_project_when_purging_project() {
  1097. LocalDateTime now = LocalDateTime.now();
  1098. ProjectData projectData1 = db.components().insertPublicProject();
  1099. ComponentDto mainBranch1 = projectData1.getMainBranchComponent();
  1100. Consumer<CeQueueDto> belongsToProject1 = t -> t.setEntityUuid(projectData1.projectUuid()).setComponentUuid(mainBranch1.uuid());
  1101. ProjectData projectData2 = db.components().insertPublicProject();
  1102. ComponentDto project2 = projectData2.getMainBranchComponent();
  1103. Consumer<CeQueueDto> belongsToProject2 = t -> t.setEntityUuid(projectData2.projectUuid()).setComponentUuid(project2.uuid());
  1104. insertCeActivityAndChildDataWithDate("VERY_OLD_1", now.minusDays(180).minusMonths(10), belongsToProject1);
  1105. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_1", now.minusDays(180).minusDays(1), belongsToProject1);
  1106. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_1", now.minusDays(180), belongsToProject1);
  1107. insertCeActivityAndChildDataWithDate("RECENT_1", now.minusDays(1), belongsToProject1);
  1108. insertCeActivityAndChildDataWithDate("VERY_OLD_2", now.minusDays(180).minusMonths(10), belongsToProject2);
  1109. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_2", now.minusDays(180).minusDays(1), belongsToProject2);
  1110. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_2", now.minusDays(180), belongsToProject2);
  1111. insertCeActivityAndChildDataWithDate("RECENT_2", now.minusDays(1), belongsToProject2);
  1112. when(system2.now()).thenReturn(now.toInstant(ZoneOffset.UTC).toEpochMilli());
  1113. underTest.purge(db.getSession(), newConfigurationWith30Days(System2.INSTANCE, mainBranch1.uuid(), projectData1.projectUuid()),
  1114. PurgeListener.EMPTY, new PurgeProfiler());
  1115. assertThat(selectActivity("VERY_OLD_1")).isEmpty();
  1116. assertThat(selectTaskInput("VERY_OLD_1")).isEmpty();
  1117. assertThat(selectTaskCharacteristic("VERY_OLD_1")).isEmpty();
  1118. assertThat(scannerContextExists("VERY_OLD_1")).isFalse();
  1119. assertThat(selectActivity("VERY_OLD_2")).isNotEmpty();
  1120. assertThat(selectTaskInput("VERY_OLD_2")).isNotEmpty();
  1121. assertThat(selectTaskCharacteristic("VERY_OLD_2")).hasSize(1);
  1122. assertThat(scannerContextExists("VERY_OLD_2")).isTrue();
  1123. assertThat(selectActivity("JUST_OLD_ENOUGH_1")).isEmpty();
  1124. assertThat(selectTaskInput("JUST_OLD_ENOUGH_1")).isEmpty();
  1125. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_1")).isEmpty();
  1126. assertThat(scannerContextExists("JUST_OLD_ENOUGH_1")).isFalse();
  1127. assertThat(selectActivity("JUST_OLD_ENOUGH_2")).isNotEmpty();
  1128. assertThat(selectTaskInput("JUST_OLD_ENOUGH_2")).isNotEmpty();
  1129. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_2")).hasSize(1);
  1130. assertThat(scannerContextExists("JUST_OLD_ENOUGH_2")).isTrue();
  1131. assertThat(selectActivity("NOT_OLD_ENOUGH_1")).isNotEmpty();
  1132. assertThat(selectTaskInput("NOT_OLD_ENOUGH_1")).isNotEmpty();
  1133. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_1")).hasSize(1);
  1134. assertThat(scannerContextExists("NOT_OLD_ENOUGH_1")).isFalse(); // because more than 4 weeks old
  1135. assertThat(selectActivity("NOT_OLD_ENOUGH_2")).isNotEmpty();
  1136. assertThat(selectTaskInput("NOT_OLD_ENOUGH_2")).isNotEmpty();
  1137. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_2")).hasSize(1);
  1138. assertThat(scannerContextExists("NOT_OLD_ENOUGH_2")).isTrue();
  1139. assertThat(selectActivity("RECENT_1")).isNotEmpty();
  1140. assertThat(selectTaskInput("RECENT_1")).isNotEmpty();
  1141. assertThat(selectTaskCharacteristic("RECENT_1")).hasSize(1);
  1142. assertThat(scannerContextExists("RECENT_1")).isTrue();
  1143. assertThat(selectActivity("RECENT_2")).isNotEmpty();
  1144. assertThat(selectTaskInput("RECENT_2")).isNotEmpty();
  1145. assertThat(selectTaskCharacteristic("RECENT_2")).hasSize(1);
  1146. assertThat(scannerContextExists("RECENT_2")).isTrue();
  1147. }
  1148. @Test
  1149. public void delete_ce_analysis_older_than_180_and_scanner_context_older_than_40_days_of_project_and_branches_when_purging_project() {
  1150. LocalDateTime now = LocalDateTime.now();
  1151. ProjectData projectData = db.components().insertPublicProject();
  1152. ComponentDto mainBranch1 = projectData.getMainBranchComponent();
  1153. ComponentDto branch1 = db.components().insertProjectBranch(mainBranch1, b -> b.setExcludeFromPurge(true));
  1154. Consumer<CeQueueDto> belongsToMainBranch1 = t -> t.setEntityUuid(projectData.projectUuid()).setComponentUuid(mainBranch1.uuid());
  1155. Consumer<CeQueueDto> belongsToBranch1 = t -> t.setEntityUuid(projectData.projectUuid()).setComponentUuid(branch1.uuid());
  1156. insertCeActivityAndChildDataWithDate("VERY_OLD_1", now.minusDays(180).minusMonths(10), belongsToMainBranch1);
  1157. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_1", now.minusDays(180).minusDays(1), belongsToMainBranch1);
  1158. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_1", now.minusDays(180), belongsToMainBranch1);
  1159. insertCeActivityAndChildDataWithDate("RECENT_1", now.minusDays(1), belongsToMainBranch1);
  1160. insertCeActivityAndChildDataWithDate("VERY_OLD_2", now.minusDays(180).minusMonths(10), belongsToBranch1);
  1161. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_2", now.minusDays(180).minusDays(1), belongsToBranch1);
  1162. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_2", now.minusDays(180), belongsToBranch1);
  1163. insertCeActivityAndChildDataWithDate("RECENT_2", now.minusDays(1), belongsToBranch1);
  1164. when(system2.now()).thenReturn(now.toInstant(ZoneOffset.UTC).toEpochMilli());
  1165. underTest.purge(db.getSession(), newConfigurationWith30Days(System2.INSTANCE, mainBranch1.uuid(), projectData.projectUuid()),
  1166. PurgeListener.EMPTY, new PurgeProfiler());
  1167. assertThat(selectActivity("VERY_OLD_1")).isEmpty();
  1168. assertThat(selectTaskInput("VERY_OLD_1")).isEmpty();
  1169. assertThat(selectTaskCharacteristic("VERY_OLD_1")).isEmpty();
  1170. assertThat(scannerContextExists("VERY_OLD_1")).isFalse();
  1171. assertThat(selectActivity("VERY_OLD_2")).isEmpty();
  1172. assertThat(selectTaskInput("VERY_OLD_2")).isEmpty();
  1173. assertThat(selectTaskCharacteristic("VERY_OLD_2")).isEmpty();
  1174. assertThat(scannerContextExists("VERY_OLD_2")).isFalse();
  1175. assertThat(selectActivity("JUST_OLD_ENOUGH_1")).isEmpty();
  1176. assertThat(selectTaskInput("JUST_OLD_ENOUGH_1")).isEmpty();
  1177. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_1")).isEmpty();
  1178. assertThat(scannerContextExists("JUST_OLD_ENOUGH_1")).isFalse();
  1179. assertThat(selectActivity("JUST_OLD_ENOUGH_2")).isEmpty();
  1180. assertThat(selectTaskInput("JUST_OLD_ENOUGH_2")).isEmpty();
  1181. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_2")).isEmpty();
  1182. assertThat(scannerContextExists("JUST_OLD_ENOUGH_2")).isFalse();
  1183. assertThat(selectActivity("NOT_OLD_ENOUGH_1")).isNotEmpty();
  1184. assertThat(selectTaskInput("NOT_OLD_ENOUGH_1")).isNotEmpty();
  1185. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_1")).hasSize(1);
  1186. assertThat(scannerContextExists("NOT_OLD_ENOUGH_1")).isFalse(); // because more than 4 weeks old
  1187. assertThat(selectActivity("NOT_OLD_ENOUGH_2")).isNotEmpty();
  1188. assertThat(selectTaskInput("NOT_OLD_ENOUGH_2")).isNotEmpty();
  1189. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_2")).hasSize(1);
  1190. assertThat(scannerContextExists("NOT_OLD_ENOUGH_2")).isFalse(); // because more than 4 weeks old
  1191. assertThat(selectActivity("RECENT_1")).isNotEmpty();
  1192. assertThat(selectTaskInput("RECENT_1")).isNotEmpty();
  1193. assertThat(selectTaskCharacteristic("RECENT_1")).hasSize(1);
  1194. assertThat(scannerContextExists("RECENT_1")).isTrue();
  1195. assertThat(selectActivity("RECENT_2")).isNotEmpty();
  1196. assertThat(selectTaskInput("RECENT_2")).isNotEmpty();
  1197. assertThat(selectTaskCharacteristic("RECENT_2")).hasSize(1);
  1198. assertThat(scannerContextExists("RECENT_2")).isTrue();
  1199. }
  1200. @Test
  1201. public void delete_ce_analysis_of_branch_older_than_180_and_scanner_context_older_than_40_days_when_purging_branch() {
  1202. LocalDateTime now = LocalDateTime.now();
  1203. ProjectData projectData1 = db.components().insertPublicProject();
  1204. ComponentDto mainBranch1 = projectData1.getMainBranchComponent();
  1205. ComponentDto branch1 = db.components().insertProjectBranch(mainBranch1);
  1206. Consumer<CeQueueDto> belongsToProject1 = t -> t.setEntityUuid(mainBranch1.uuid()).setComponentUuid(mainBranch1.uuid());
  1207. Consumer<CeQueueDto> belongsToBranch1 = t -> t.setEntityUuid(mainBranch1.uuid()).setComponentUuid(branch1.uuid());
  1208. insertCeActivityAndChildDataWithDate("VERY_OLD_1", now.minusDays(180).minusMonths(10), belongsToProject1);
  1209. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_1", now.minusDays(180).minusDays(1), belongsToProject1);
  1210. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_1", now.minusDays(180), belongsToProject1);
  1211. insertCeActivityAndChildDataWithDate("RECENT_1", now.minusDays(1), belongsToProject1);
  1212. insertCeActivityAndChildDataWithDate("VERY_OLD_2", now.minusDays(180).minusMonths(10), belongsToBranch1);
  1213. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_2", now.minusDays(180).minusDays(1), belongsToBranch1);
  1214. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_2", now.minusDays(180), belongsToBranch1);
  1215. insertCeActivityAndChildDataWithDate("RECENT_2", now.minusDays(1), belongsToBranch1);
  1216. when(system2.now()).thenReturn(now.toInstant(ZoneOffset.UTC).toEpochMilli());
  1217. underTest.purge(db.getSession(), newConfigurationWith30Days(System2.INSTANCE, branch1.uuid(), projectData1.projectUuid()),
  1218. PurgeListener.EMPTY, new PurgeProfiler());
  1219. assertThat(selectActivity("VERY_OLD_1")).isNotEmpty();
  1220. assertThat(selectTaskInput("VERY_OLD_1")).isNotEmpty();
  1221. assertThat(selectTaskCharacteristic("VERY_OLD_1")).hasSize(1);
  1222. assertThat(scannerContextExists("VERY_OLD_1")).isTrue();
  1223. assertThat(selectActivity("VERY_OLD_2")).isEmpty();
  1224. assertThat(selectTaskInput("VERY_OLD_2")).isEmpty();
  1225. assertThat(selectTaskCharacteristic("VERY_OLD_2")).isEmpty();
  1226. assertThat(scannerContextExists("VERY_OLD_2")).isFalse();
  1227. assertThat(selectActivity("JUST_OLD_ENOUGH_1")).isNotEmpty();
  1228. assertThat(selectTaskInput("JUST_OLD_ENOUGH_1")).isNotEmpty();
  1229. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_1")).hasSize(1);
  1230. assertThat(scannerContextExists("JUST_OLD_ENOUGH_1")).isTrue();
  1231. assertThat(selectActivity("JUST_OLD_ENOUGH_2")).isEmpty();
  1232. assertThat(selectTaskInput("JUST_OLD_ENOUGH_2")).isEmpty();
  1233. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_2")).isEmpty();
  1234. assertThat(scannerContextExists("JUST_OLD_ENOUGH_2")).isFalse();
  1235. assertThat(selectActivity("NOT_OLD_ENOUGH_1")).isNotEmpty();
  1236. assertThat(selectTaskInput("NOT_OLD_ENOUGH_1")).isNotEmpty();
  1237. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_1")).hasSize(1);
  1238. assertThat(scannerContextExists("NOT_OLD_ENOUGH_1")).isTrue();
  1239. assertThat(selectActivity("NOT_OLD_ENOUGH_2")).isNotEmpty();
  1240. assertThat(selectTaskInput("NOT_OLD_ENOUGH_2")).isNotEmpty();
  1241. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_2")).hasSize(1);
  1242. assertThat(scannerContextExists("NOT_OLD_ENOUGH_2")).isFalse(); // because more than 4 weeks old
  1243. assertThat(selectActivity("RECENT_1")).isNotEmpty();
  1244. assertThat(selectTaskInput("RECENT_1")).isNotEmpty();
  1245. assertThat(selectTaskCharacteristic("RECENT_1")).hasSize(1);
  1246. assertThat(scannerContextExists("RECENT_1")).isTrue();
  1247. assertThat(selectActivity("RECENT_2")).isNotEmpty();
  1248. assertThat(selectTaskInput("RECENT_2")).isNotEmpty();
  1249. assertThat(selectTaskCharacteristic("RECENT_2")).hasSize(1);
  1250. assertThat(scannerContextExists("RECENT_2")).isTrue();
  1251. }
  1252. @Test
  1253. public void deleteProject_deletes_webhook_deliveries() {
  1254. ComponentDto project = db.components().insertPublicProject().getMainBranchComponent();
  1255. dbClient.webhookDeliveryDao().insert(dbSession, newDto().setProjectUuid(project.uuid()).setUuid("D1").setDurationMs(1000).setWebhookUuid("webhook-uuid"));
  1256. dbClient.webhookDeliveryDao().insert(dbSession, newDto().setProjectUuid("P2").setUuid("D2").setDurationMs(1000).setWebhookUuid("webhook-uuid"));
  1257. underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey());
  1258. assertThat(selectAllDeliveryUuids(db, dbSession)).containsOnly("D2");
  1259. }
  1260. @Test
  1261. public void deleteProject_deletes_project_alm_settings() {
  1262. ProjectDto project = db.components().insertPublicProject().getProjectDto();
  1263. ProjectDto otherProject = db.components().insertPublicProject().getProjectDto();
  1264. AlmSettingDto almSettingDto = db.almSettings().insertGitlabAlmSetting();
  1265. db.almSettings().insertGitlabProjectAlmSetting(almSettingDto, project);
  1266. db.almSettings().insertGitlabProjectAlmSetting(almSettingDto, otherProject);
  1267. underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier(), project.getName(), project.getKey());
  1268. assertThat(dbClient.projectAlmSettingDao().selectByProject(dbSession, project)).isEmpty();
  1269. assertThat(dbClient.projectAlmSettingDao().selectByProject(dbSession, otherProject)).isNotEmpty();
  1270. }
  1271. @Test
  1272. public void deleteBranch_deletes_scanner_cache() throws IOException {
  1273. ProjectDto project = db.components().insertPublicProject().getProjectDto();
  1274. BranchDto branch = db.components().insertProjectBranch(project);
  1275. dbClient.scannerAnalysisCacheDao().insert(dbSession, branch.getUuid(), IOUtils.toInputStream("test1", UTF_8));
  1276. dbClient.scannerAnalysisCacheDao().insert(dbSession, project.getUuid(), IOUtils.toInputStream("test2", UTF_8));
  1277. underTest.deleteBranch(dbSession, branch.getUuid());
  1278. assertThat(dbClient.scannerAnalysisCacheDao().selectData(dbSession, branch.getUuid())).isNull();
  1279. DbInputStream mainBranchCache = dbClient.scannerAnalysisCacheDao().selectData(dbSession, project.getUuid());
  1280. assertThat(IOUtils.toString(mainBranchCache, UTF_8)).isEqualTo("test2");
  1281. }
  1282. @Test
  1283. public void deleteProject_deletes_scanner_cache() throws IOException {
  1284. ProjectDto project = db.components().insertPublicProject().getProjectDto();
  1285. BranchDto branch = db.components().insertProjectBranch(project);
  1286. dbClient.scannerAnalysisCacheDao().insert(dbSession, branch.getUuid(), IOUtils.toInputStream("test1", UTF_8));
  1287. dbClient.scannerAnalysisCacheDao().insert(dbSession, project.getUuid(), IOUtils.toInputStream("test2", UTF_8));
  1288. underTest.deleteProject(dbSession, project.getUuid(), Qualifiers.PROJECT, "project", "project");
  1289. assertThat(dbClient.scannerAnalysisCacheDao().selectData(dbSession, project.getUuid())).isNull();
  1290. assertThat(dbClient.scannerAnalysisCacheDao().selectData(dbSession, branch.getUuid())).isNull();
  1291. }
  1292. @Test
  1293. public void deleteProject_deletes_project_badge_tokens() {
  1294. ProjectDto project = db.components().insertPublicProject().getProjectDto();
  1295. ProjectDto otherProject = db.components().insertPublicProject().getProjectDto();
  1296. dbClient.projectBadgeTokenDao().insert(dbSession, "token_to_delete", project, "user-uuid", "user-login");
  1297. dbClient.projectBadgeTokenDao().insert(dbSession, "token_to_not_delete", otherProject, "user-uuid", "user-login");
  1298. underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier(), project.getName(), project.getKey());
  1299. assertThat(dbClient.projectBadgeTokenDao().selectTokenByProject(dbSession, project)).isNull();
  1300. assertThat(dbClient.projectBadgeTokenDao().selectTokenByProject(dbSession, otherProject)).isNotNull();
  1301. }
  1302. @Test
  1303. public void deleteProject_deletes_portfolio_projects() {
  1304. ComponentDto portfolio1 = db.components().insertPrivatePortfolio();
  1305. ComponentDto portfolio2 = db.components().insertPrivatePortfolio();
  1306. ProjectDto project = db.components().insertPublicProject().getProjectDto();
  1307. ProjectDto otherProject = db.components().insertPublicProject().getProjectDto();
  1308. db.components().addPortfolioProject(portfolio1, project.getUuid(), otherProject.getUuid());
  1309. db.components().addPortfolioProject(portfolio2, project.getUuid());
  1310. underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier(), project.getName(), project.getKey());
  1311. assertThat(dbClient.portfolioDao().selectAllPortfolioProjects(dbSession))
  1312. .extracting(PortfolioProjectDto::getPortfolioUuid, PortfolioProjectDto::getProjectUuid)
  1313. .containsExactlyInAnyOrder(tuple(portfolio1.uuid(), otherProject.getUuid()));
  1314. }
  1315. @Test
  1316. public void deleteProject_deletes_app_projects() {
  1317. ProjectDto app = db.components().insertPrivateApplication().getProjectDto();
  1318. BranchDto appBranch = db.components().insertProjectBranch(app);
  1319. ProjectDto project = db.components().insertPublicProject().getProjectDto();
  1320. BranchDto projectBranch = db.components().insertProjectBranch(project);
  1321. ProjectDto otherProject = db.components().insertPublicProject().getProjectDto();
  1322. db.components().addApplicationProject(app, project, otherProject);
  1323. db.components().addProjectBranchToApplicationBranch(appBranch, projectBranch);
  1324. assertThat(db.countRowsOfTable("app_branch_project_branch")).isOne();
  1325. underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier(), project.getName(), project.getKey());
  1326. assertThat(dbClient.applicationProjectsDao().selectProjects(dbSession, app.getUuid()))
  1327. .extracting(ProjectDto::getUuid)
  1328. .containsExactlyInAnyOrder(otherProject.getUuid());
  1329. assertThat(db.countRowsOfTable("app_branch_project_branch")).isZero();
  1330. }
  1331. @Test
  1332. public void deleteNonRootComponents_has_no_effect_when_parameter_is_empty() {
  1333. DbSession dbSession = mock(DbSession.class);
  1334. underTest.deleteNonRootComponentsInView(dbSession, Collections.emptyList());
  1335. verifyNoInteractions(dbSession);
  1336. }
  1337. @Test
  1338. public void deleteNonRootComponents_has_no_effect_when_parameter_contains_only_projects_and_or_views() {
  1339. ComponentDbTester componentDbTester = db.components();
  1340. verifyNoEffect(componentDbTester.insertPrivateProject().getMainBranchComponent());
  1341. verifyNoEffect(componentDbTester.insertPublicProject().getMainBranchComponent());
  1342. verifyNoEffect(componentDbTester.insertPrivatePortfolio());
  1343. verifyNoEffect(componentDbTester.insertPrivatePortfolio(), componentDbTester.insertPrivateProject().getMainBranchComponent(), componentDbTester.insertPublicProject().getMainBranchComponent());
  1344. }
  1345. @Test
  1346. public void delete_live_measures_when_deleting_project() {
  1347. MetricDto metric = db.measures().insertMetric();
  1348. ComponentDto project1 = db.components().insertPublicProject().getMainBranchComponent();
  1349. ComponentDto dir1 = db.components().insertComponent(newDirectory(project1, "path"));
  1350. db.measures().insertLiveMeasure(project1, metric);
  1351. db.measures().insertLiveMeasure(dir1, metric);
  1352. ComponentDto project2 = db.components().insertPublicProject().getMainBranchComponent();
  1353. ComponentDto dir2 = db.components().insertComponent(newDirectory(project2, "path"));
  1354. db.measures().insertLiveMeasure(project2, metric);
  1355. db.measures().insertLiveMeasure(dir2, metric);
  1356. underTest.deleteProject(dbSession, project1.uuid(), project1.qualifier(), project1.name(), project1.getKey());
  1357. assertThat(dbClient.liveMeasureDao().selectByComponentUuidsAndMetricUuids(dbSession, asList(project1.uuid(), dir1.uuid()), asList(metric.getUuid()))).isEmpty();
  1358. assertThat(dbClient.liveMeasureDao().selectByComponentUuidsAndMetricUuids(dbSession, asList(project2.uuid(), dir2.uuid()), asList(metric.getUuid()))).hasSize(2);
  1359. }
  1360. private void verifyNoEffect(ComponentDto firstRoot, ComponentDto... otherRoots) {
  1361. DbSession dbSession = mock(DbSession.class);
  1362. List<ComponentDto> componentDtos = Stream.concat(Stream.of(firstRoot), Arrays.stream(otherRoots)).collect(Collectors.toCollection(ArrayList::new));
  1363. Collections.shuffle(componentDtos); // order of collection must not matter
  1364. underTest.deleteNonRootComponentsInView(dbSession, componentDtos);
  1365. verifyNoInteractions(dbSession);
  1366. }
  1367. @Test
  1368. public void deleteNonRootComponents_deletes_only_non_root_components_of_a_project_from_table_components() {
  1369. ComponentDto project = new Random().nextBoolean() ? db.components().insertPublicProject().getMainBranchComponent() : db.components().insertPrivateProject().getMainBranchComponent();
  1370. ComponentDto dir1 = db.components().insertComponent(newDirectory(project, "A/B"));
  1371. ComponentDto file1 = db.components().insertComponent(newFileDto(project, dir1));
  1372. List<ComponentDto> components = asList(
  1373. project,
  1374. dir1,
  1375. file1,
  1376. db.components().insertComponent(newFileDto(dir1)),
  1377. db.components().insertComponent(newFileDto(file1)),
  1378. db.components().insertComponent(newFileDto(project)));
  1379. Collections.shuffle(components);
  1380. underTest.deleteNonRootComponentsInView(dbSession, components);
  1381. assertThat(uuidsIn(" components"))
  1382. .containsOnly(project.uuid());
  1383. }
  1384. @Test
  1385. public void deleteNonRootComponents_deletes_only_non_root_components_of_a_view_from_table_components() {
  1386. ComponentDto[] projects = {
  1387. db.components().insertPrivateProject().getMainBranchComponent(),
  1388. db.components().insertPrivateProject().getMainBranchComponent(),
  1389. db.components().insertPrivateProject().getMainBranchComponent()
  1390. };
  1391. ComponentDto view = db.components().insertPrivatePortfolio();
  1392. ComponentDto subview1 = db.components().insertComponent(newSubPortfolio(view));
  1393. ComponentDto subview2 = db.components().insertComponent(newSubPortfolio(subview1));
  1394. List<ComponentDto> components = asList(
  1395. view,
  1396. subview1,
  1397. subview2,
  1398. db.components().insertComponent(newProjectCopy("a", projects[0], view)),
  1399. db.components().insertComponent(newProjectCopy("b", projects[1], subview1)),
  1400. db.components().insertComponent(newProjectCopy("c", projects[2], subview2)));
  1401. Collections.shuffle(components);
  1402. underTest.deleteNonRootComponentsInView(dbSession, components);
  1403. assertThat(uuidsIn(" components"))
  1404. .containsOnly(view.uuid(), projects[0].uuid(), projects[1].uuid(), projects[2].uuid());
  1405. }
  1406. @Test
  1407. public void deleteNonRootComponents_deletes_only_specified_non_root_components_of_a_project_from_table_components() {
  1408. ComponentDto project = new Random().nextBoolean() ? db.components().insertPublicProject().getMainBranchComponent() : db.components().insertPrivateProject().getMainBranchComponent();
  1409. ComponentDto dir1 = db.components().insertComponent(newDirectory(project, "A/B"));
  1410. ComponentDto dir2 = db.components().insertComponent(newDirectory(project, "A/C"));
  1411. ComponentDto file1 = db.components().insertComponent(newFileDto(project, dir1));
  1412. ComponentDto file2 = db.components().insertComponent(newFileDto(project));
  1413. ComponentDto file3 = db.components().insertComponent(newFileDto(project));
  1414. underTest.deleteNonRootComponentsInView(dbSession, singletonList(file3));
  1415. assertThat(uuidsIn("components"))
  1416. .containsOnly(project.uuid(), dir1.uuid(), dir2.uuid(), file1.uuid(), file2.uuid());
  1417. underTest.deleteNonRootComponentsInView(dbSession, asList(dir2, file1));
  1418. assertThat(uuidsIn("components"))
  1419. .containsOnly(project.uuid(), dir1.uuid(), file2.uuid());
  1420. }
  1421. @Test
  1422. public void deleteNonRootComponents_deletes_only_specified_non_root_components_of_a_view_from_table_components() {
  1423. ProjectData[] projects = {
  1424. db.components().insertPrivateProject(),
  1425. db.components().insertPrivateProject(),
  1426. db.components().insertPrivateProject()
  1427. };
  1428. ComponentDto view = db.components().insertPrivatePortfolio();
  1429. ComponentDto subview1 = db.components().insertComponent(newSubPortfolio(view));
  1430. ComponentDto subview2 = db.components().insertComponent(newSubPortfolio(subview1));
  1431. ComponentDto pc1 = db.components().insertComponent(newProjectCopy("a", projects[0].getMainBranchComponent(), view));
  1432. ComponentDto pc2 = db.components().insertComponent(newProjectCopy("b", projects[1].getMainBranchComponent(), subview1));
  1433. ComponentDto pc3 = db.components().insertComponent(newProjectCopy("c", projects[2].getMainBranchComponent(), subview2));
  1434. underTest.deleteNonRootComponentsInView(dbSession, singletonList(pc3));
  1435. assertThat(uuidsIn("components"))
  1436. .containsOnly(view.uuid(), projects[0].getMainBranchComponent().uuid(), projects[1].getMainBranchComponent().uuid(), projects[2].getMainBranchComponent().uuid(),
  1437. subview1.uuid(), subview2.uuid(), pc1.uuid(), pc2.uuid());
  1438. underTest.deleteNonRootComponentsInView(dbSession, asList(subview1, pc2));
  1439. assertThat(uuidsIn("components"))
  1440. .containsOnly(view.uuid(), projects[0].getMainBranchComponent().uuid(), projects[1].getMainBranchComponent().uuid(), projects[2].getMainBranchComponent().uuid(), subview2.uuid(), pc1.uuid());
  1441. assertThat(uuidsIn("projects")).containsOnly(projects[0].getProjectDto().getUuid(), projects[1].getProjectDto().getUuid(), projects[2].getProjectDto().getUuid());
  1442. }
  1443. @Test
  1444. public void deleteNonRootComponents_deletes_measures_of_any_non_root_component_of_a_view() {
  1445. ComponentDto view = db.components().insertPrivatePortfolio();
  1446. ComponentDto subview = db.components().insertComponent(newSubPortfolio(view));
  1447. ComponentDto pc = db.components().insertComponent(newProjectCopy("a", db.components().insertPrivateProject().getMainBranchComponent(), view));
  1448. insertMeasureFor(view, subview, pc);
  1449. assertThat(getComponentUuidsOfMeasures()).containsOnly(view.uuid(), subview.uuid(), pc.uuid());
  1450. underTest.deleteNonRootComponentsInView(dbSession, singletonList(pc));
  1451. assertThat(getComponentUuidsOfMeasures())
  1452. .containsOnly(view.uuid(), subview.uuid());
  1453. underTest.deleteNonRootComponentsInView(dbSession, singletonList(subview));
  1454. assertThat(getComponentUuidsOfMeasures())
  1455. .containsOnly(view.uuid());
  1456. }
  1457. @Test
  1458. public void deleteNonRootComponents_deletes_properties_of_subviews_of_a_view() {
  1459. ComponentDto view = db.components().insertPrivatePortfolio();
  1460. ComponentDto subview1 = db.components().insertComponent(newSubPortfolio(view));
  1461. ComponentDto subview2 = db.components().insertComponent(newSubPortfolio(subview1));
  1462. ComponentDto subview3 = db.components().insertComponent(newSubPortfolio(view));
  1463. ComponentDto pc = db.components().insertComponent(newProjectCopy("a", db.components().insertPrivateProject().getMainBranchComponent(), view));
  1464. insertPropertyFor(view, subview1, subview2, subview3, pc);
  1465. insertReportScheduleAndSubscriptionForPortfolio("uuid", view.uuid(), dbSession);
  1466. insertReportScheduleAndSubscriptionForPortfolio("uuid2", subview1.uuid(), dbSession);
  1467. insertReportScheduleAndSubscriptionForPortfolio("uuid3", subview3.uuid(), dbSession);
  1468. assertThat(getResourceIdOfProperties()).containsOnly(view.uuid(), subview1.uuid(), subview2.uuid(), subview3.uuid(), pc.uuid());
  1469. underTest.deleteNonRootComponentsInView(dbSession, singletonList(subview1));
  1470. assertThat(getResourceIdOfProperties())
  1471. .containsOnly(view.uuid(), subview2.uuid(), subview3.uuid(), pc.uuid());
  1472. assertThat(uuidsIn("report_schedules", "portfolio_uuid")).containsOnly(view.uuid(), subview3.uuid());
  1473. assertThat(uuidsIn("report_subscriptions", "portfolio_uuid")).containsOnly(view.uuid(), subview3.uuid());
  1474. underTest.deleteNonRootComponentsInView(dbSession, asList(subview2, subview3, pc));
  1475. assertThat(getResourceIdOfProperties())
  1476. .containsOnly(view.uuid(), pc.uuid());
  1477. assertThat(uuidsIn("report_schedules", "portfolio_uuid")).containsOnly(view.uuid());
  1478. assertThat(uuidsIn("report_subscriptions", "portfolio_uuid")).containsOnly(view.uuid());
  1479. }
  1480. @Test
  1481. public void purgeCeActivities_deletes_activity_older_than_180_days_and_their_scanner_context() {
  1482. LocalDateTime now = LocalDateTime.now();
  1483. insertCeActivityAndChildDataWithDate("VERY_OLD", now.minusDays(180).minusMonths(10));
  1484. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH", now.minusDays(180).minusDays(1));
  1485. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH", now.minusDays(180));
  1486. insertCeActivityAndChildDataWithDate("RECENT", now.minusDays(1));
  1487. when(system2.now()).thenReturn(now.toInstant(ZoneOffset.UTC).toEpochMilli());
  1488. underTest.purgeCeActivities(db.getSession(), new PurgeProfiler());
  1489. assertThat(selectActivity("VERY_OLD")).isEmpty();
  1490. assertThat(selectTaskInput("VERY_OLD")).isEmpty();
  1491. assertThat(selectTaskCharacteristic("VERY_OLD")).isEmpty();
  1492. assertThat(scannerContextExists("VERY_OLD")).isFalse();
  1493. assertThat(selectActivity("JUST_OLD_ENOUGH")).isEmpty();
  1494. assertThat(selectTaskInput("JUST_OLD_ENOUGH")).isEmpty();
  1495. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH")).isEmpty();
  1496. assertThat(scannerContextExists("JUST_OLD_ENOUGH")).isFalse();
  1497. assertThat(selectActivity("NOT_OLD_ENOUGH")).isNotEmpty();
  1498. assertThat(selectTaskInput("NOT_OLD_ENOUGH")).isNotEmpty();
  1499. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH")).hasSize(1);
  1500. assertThat(scannerContextExists("NOT_OLD_ENOUGH")).isTrue();
  1501. assertThat(selectActivity("RECENT")).isNotEmpty();
  1502. assertThat(selectTaskInput("RECENT")).isNotEmpty();
  1503. assertThat(selectTaskCharacteristic("RECENT")).hasSize(1);
  1504. assertThat(scannerContextExists("RECENT")).isTrue();
  1505. }
  1506. @Test
  1507. public void purgeCeScannerContexts_deletes_ce_scanner_context_older_than_28_days() {
  1508. LocalDateTime now = LocalDateTime.now();
  1509. insertCeActivityAndChildDataWithDate("VERY_OLD", now.minusDays(28).minusMonths(12));
  1510. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH", now.minusDays(28).minusDays(1));
  1511. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH", now.minusDays(28));
  1512. insertCeActivityAndChildDataWithDate("RECENT", now.minusDays(1));
  1513. when(system2.now()).thenReturn(now.toInstant(ZoneOffset.UTC).toEpochMilli());
  1514. underTest.purgeCeScannerContexts(db.getSession(), new PurgeProfiler());
  1515. assertThat(scannerContextExists("VERY_OLD")).isFalse();
  1516. assertThat(scannerContextExists("JUST_OLD_ENOUGH")).isFalse();
  1517. assertThat(scannerContextExists("NOT_OLD_ENOUGH")).isTrue();
  1518. assertThat(scannerContextExists("RECENT")).isTrue();
  1519. }
  1520. private Optional<CeActivityDto> selectActivity(String taskUuid) {
  1521. return db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), taskUuid);
  1522. }
  1523. private List<CeTaskCharacteristicDto> selectTaskCharacteristic(String taskUuid) {
  1524. return db.getDbClient().ceTaskCharacteristicsDao().selectByTaskUuids(db.getSession(), Collections.singletonList(taskUuid));
  1525. }
  1526. private Optional<DbInputStream> selectTaskInput(String taskUuid) {
  1527. return db.getDbClient().ceTaskInputDao().selectData(db.getSession(), taskUuid);
  1528. }
  1529. private boolean scannerContextExists(String uuid) {
  1530. return db.countSql("select count(1) from ce_scanner_context where task_uuid = '" + uuid + "'") == 1;
  1531. }
  1532. @SafeVarargs
  1533. private final void insertCeActivityAndChildDataWithDate(String ceActivityUuid, LocalDateTime dateTime,
  1534. Consumer<CeQueueDto>... queueDtoConsumers) {
  1535. long date = dateTime.toInstant(UTC).toEpochMilli();
  1536. CeQueueDto queueDto = new CeQueueDto();
  1537. queueDto.setUuid(ceActivityUuid);
  1538. queueDto.setTaskType(CeTaskTypes.REPORT);
  1539. Arrays.stream(queueDtoConsumers).forEach(t -> t.accept(queueDto));
  1540. CeActivityDto dto = new CeActivityDto(queueDto);
  1541. dto.setStatus(CeActivityDto.Status.SUCCESS);
  1542. when(system2.now()).thenReturn(date);
  1543. insertCeTaskInput(dto.getUuid());
  1544. insertCeTaskCharacteristics(dto.getUuid(), 1);
  1545. insertCeScannerContext(dto.getUuid());
  1546. insertCeTaskMessages(dto.getUuid(), 2);
  1547. db.getDbClient().ceActivityDao().insert(db.getSession(), dto);
  1548. db.getSession().commit();
  1549. }
  1550. private Stream<String> getResourceIdOfProperties() {
  1551. return db.select("select entity_uuid as \"uuid\" from properties").stream()
  1552. .map(row -> (String) row.get("uuid"));
  1553. }
  1554. private void insertPropertyFor(ComponentDto... components) {
  1555. Stream.of(components).forEach(componentDto -> db.properties().insertProperty(new PropertyDto()
  1556. .setKey(randomAlphabetic(3))
  1557. .setValue(randomAlphabetic(3))
  1558. .setEntityUuid(componentDto.uuid()),
  1559. componentDto.getKey(), componentDto.name(), componentDto.qualifier(), null));
  1560. }
  1561. private void insertPropertyFor(Collection<BranchDto> branches) {
  1562. branches.stream().forEach(branchDto -> db.properties().insertProperty(new PropertyDto()
  1563. .setKey(randomAlphabetic(3))
  1564. .setValue(randomAlphabetic(3))
  1565. .setEntityUuid(branchDto.getUuid()),
  1566. null, branchDto.getKey(), null, null));
  1567. }
  1568. private Stream<String> getComponentUuidsOfMeasures() {
  1569. return db.select("select component_uuid as \"COMPONENT_UUID\" from project_measures").stream()
  1570. .map(row -> (String) row.get("COMPONENT_UUID"));
  1571. }
  1572. private void insertMeasureFor(ComponentDto... components) {
  1573. Arrays.stream(components).forEach(componentDto -> db.getDbClient().measureDao().insert(dbSession, new MeasureDto()
  1574. .setMetricUuid(randomAlphabetic(3))
  1575. .setComponentUuid(componentDto.uuid())
  1576. .setAnalysisUuid(randomAlphabetic(3))));
  1577. dbSession.commit();
  1578. }
  1579. private CeQueueDto createCeQueue(ComponentDto component, String entityUuid, Status status) {
  1580. CeQueueDto queueDto = new CeQueueDto();
  1581. queueDto.setUuid(Uuids.create());
  1582. queueDto.setTaskType(REPORT);
  1583. queueDto.setComponentUuid(component.uuid());
  1584. queueDto.setEntityUuid(entityUuid);
  1585. queueDto.setSubmitterUuid("submitter uuid");
  1586. queueDto.setCreatedAt(1_300_000_000_000L);
  1587. queueDto.setStatus(status);
  1588. return queueDto;
  1589. }
  1590. private CeActivityDto insertCeActivity(ComponentDto component, String entityUuid) {
  1591. Status unusedStatus = Status.values()[RandomUtils.nextInt(Status.values().length)];
  1592. CeQueueDto queueDto = createCeQueue(component, entityUuid, unusedStatus);
  1593. CeActivityDto dto = new CeActivityDto(queueDto);
  1594. dto.setStatus(CeActivityDto.Status.SUCCESS);
  1595. dto.setStartedAt(1_500_000_000_000L);
  1596. dto.setExecutedAt(1_500_000_000_500L);
  1597. dto.setExecutionTimeMs(500L);
  1598. dbClient.ceActivityDao().insert(dbSession, dto);
  1599. return dto;
  1600. }
  1601. private CeQueueDto insertCeQueue(ComponentDto component, String mainBranch) {
  1602. CeQueueDto res = new CeQueueDto()
  1603. .setUuid(UuidFactoryFast.getInstance().create())
  1604. .setTaskType("foo")
  1605. .setComponentUuid(component.uuid())
  1606. .setEntityUuid(mainBranch)
  1607. .setStatus(Status.PENDING)
  1608. .setCreatedAt(1_2323_222L)
  1609. .setUpdatedAt(1_2323_222L);
  1610. dbClient.ceQueueDao().insert(dbSession, res);
  1611. dbSession.commit();
  1612. return res;
  1613. }
  1614. private CeQueueDto insertCeQueue(ComponentDto component) {
  1615. return insertCeQueue(component, component.uuid());
  1616. }
  1617. private void insertCeScannerContext(String uuid) {
  1618. dbClient.ceScannerContextDao().insert(dbSession, uuid, CloseableIterator.from(Arrays.asList("a", "b", "c").iterator()));
  1619. dbSession.commit();
  1620. }
  1621. private void insertCeTaskCharacteristics(String uuid, int count) {
  1622. List<CeTaskCharacteristicDto> dtos = IntStream.range(0, count)
  1623. .mapToObj(i -> new CeTaskCharacteristicDto()
  1624. .setUuid(UuidFactoryFast.getInstance().create())
  1625. .setTaskUuid(uuid)
  1626. .setKey("key_" + uuid.hashCode() + i)
  1627. .setValue("value_" + uuid.hashCode() + i))
  1628. .toList();
  1629. dbClient.ceTaskCharacteristicsDao().insert(dbSession, dtos);
  1630. dbSession.commit();
  1631. }
  1632. private void insertCeTaskInput(String uuid) {
  1633. dbClient.ceTaskInputDao().insert(dbSession, uuid, new ByteArrayInputStream("some content man!".getBytes()));
  1634. dbSession.commit();
  1635. }
  1636. private void insertCeTaskMessages(String uuid, int count) {
  1637. IntStream.range(0, count)
  1638. .mapToObj(i -> new CeTaskMessageDto()
  1639. .setUuid(UuidFactoryFast.getInstance().create())
  1640. .setTaskUuid(uuid)
  1641. .setMessage("key_" + uuid.hashCode() + i)
  1642. .setType(CeTaskMessageType.GENERIC)
  1643. .setCreatedAt(2_333_444L + i))
  1644. .forEach(dto -> dbClient.ceTaskMessageDao().insert(dbSession, dto));
  1645. dbSession.commit();
  1646. }
  1647. private static PurgeableAnalysisDto getById(List<PurgeableAnalysisDto> snapshots, String uuid) {
  1648. return snapshots.stream()
  1649. .filter(snapshot -> uuid.equals(snapshot.getAnalysisUuid()))
  1650. .findFirst()
  1651. .orElse(null);
  1652. }
  1653. private Stream<String> uuidsIn(String tableName) {
  1654. return uuidsIn(tableName, "uuid");
  1655. }
  1656. private Stream<String> componentUuidsIn(String tableName) {
  1657. return uuidsIn(tableName, "entity_uuid");
  1658. }
  1659. private Stream<String> taskUuidsIn(String tableName) {
  1660. return uuidsIn(tableName, "task_uuid");
  1661. }
  1662. private Stream<String> uuidsIn(String tableName, String columnName) {
  1663. return db.select("select " + columnName + " as \"UUID\" from " + tableName)
  1664. .stream()
  1665. .map(row -> (String) row.get("UUID"));
  1666. }
  1667. private static PurgeConfiguration newConfigurationWith30Days(System2 system2, String rootUuid, String projectUuid) {
  1668. return newConfigurationWith30Days(system2, rootUuid, projectUuid, Collections.emptySet());
  1669. }
  1670. private static PurgeConfiguration newConfigurationWith30Days(System2 system2, String rootUuid, String projectUuid, Set<String> disabledComponentUuids) {
  1671. return new PurgeConfiguration(rootUuid, projectUuid, 30, Optional.of(30), system2, disabledComponentUuids);
  1672. }
  1673. private Stream<String> uuidsOfAnalysesOfRoot(ComponentDto rootComponent) {
  1674. return db.select("select uuid as \"UUID\" from snapshots where root_component_uuid='" + rootComponent.uuid() + "'")
  1675. .stream()
  1676. .map(t -> (String) t.get("UUID"));
  1677. }
  1678. private void addComponentsSnapshotsAndIssuesToBranch(ComponentDto branch, RuleDto rule, int branchAge) {
  1679. db.components().insertSnapshot(branch, dto -> dto.setCreatedAt(DateUtils.addDays(new Date(), -branchAge).getTime()));
  1680. ComponentDto dir = db.components().insertComponent(newDirectory(branch, "path"));
  1681. ComponentDto file = db.components().insertComponent(newFileDto(branch, dir));
  1682. db.issues().insert(rule, branch, file);
  1683. }
  1684. private void addComponentsSnapshotsAndIssuesToBranch(BranchDto branch, RuleDto rule, int branchAge) {
  1685. ComponentDto componentDto = db.components().getComponentDto(branch);
  1686. addComponentsSnapshotsAndIssuesToBranch(componentDto, rule, branchAge);
  1687. }
  1688. }