You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PurgeDaoTest.java 88KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2020 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.db.purge;
  21. import com.google.common.collect.ImmutableList;
  22. import com.google.common.collect.ImmutableSet;
  23. import java.io.ByteArrayInputStream;
  24. import java.time.LocalDateTime;
  25. import java.time.ZoneOffset;
  26. import java.util.Arrays;
  27. import java.util.Collections;
  28. import java.util.Date;
  29. import java.util.List;
  30. import java.util.Optional;
  31. import java.util.Random;
  32. import java.util.Set;
  33. import java.util.function.Consumer;
  34. import java.util.stream.Collectors;
  35. import java.util.stream.IntStream;
  36. import java.util.stream.Stream;
  37. import org.apache.commons.lang.math.RandomUtils;
  38. import org.apache.commons.lang.time.DateUtils;
  39. import org.junit.Rule;
  40. import org.junit.Test;
  41. import org.junit.rules.ExpectedException;
  42. import org.sonar.api.issue.Issue;
  43. import org.sonar.api.utils.System2;
  44. import org.sonar.core.util.CloseableIterator;
  45. import org.sonar.core.util.UuidFactoryFast;
  46. import org.sonar.core.util.Uuids;
  47. import org.sonar.db.DbClient;
  48. import org.sonar.db.DbSession;
  49. import org.sonar.db.DbTester;
  50. import org.sonar.db.alm.ALM;
  51. import org.sonar.db.ce.CeActivityDto;
  52. import org.sonar.db.ce.CeQueueDto;
  53. import org.sonar.db.ce.CeQueueDto.Status;
  54. import org.sonar.db.ce.CeTaskCharacteristicDto;
  55. import org.sonar.db.ce.CeTaskInputDao;
  56. import org.sonar.db.ce.CeTaskMessageDto;
  57. import org.sonar.db.ce.CeTaskTypes;
  58. import org.sonar.db.component.BranchDto;
  59. import org.sonar.db.component.BranchType;
  60. import org.sonar.db.component.ComponentDbTester;
  61. import org.sonar.db.component.ComponentDto;
  62. import org.sonar.db.component.ComponentTesting;
  63. import org.sonar.db.component.SnapshotDto;
  64. import org.sonar.db.event.EventComponentChangeDto;
  65. import org.sonar.db.event.EventDto;
  66. import org.sonar.db.event.EventTesting;
  67. import org.sonar.db.issue.IssueChangeDto;
  68. import org.sonar.db.issue.IssueDto;
  69. import org.sonar.db.measure.LiveMeasureDto;
  70. import org.sonar.db.measure.MeasureDto;
  71. import org.sonar.db.measure.custom.CustomMeasureDto;
  72. import org.sonar.db.metric.MetricDto;
  73. import org.sonar.db.newcodeperiod.NewCodePeriodDto;
  74. import org.sonar.db.newcodeperiod.NewCodePeriodType;
  75. import org.sonar.db.organization.OrganizationDto;
  76. import org.sonar.db.project.ProjectDto;
  77. import org.sonar.db.property.PropertyDto;
  78. import org.sonar.db.rule.RuleDefinitionDto;
  79. import org.sonar.db.source.FileSourceDto;
  80. import org.sonar.db.webhook.WebhookDeliveryLiteDto;
  81. import org.sonar.db.webhook.WebhookDto;
  82. import static com.google.common.base.MoreObjects.firstNonNull;
  83. import static java.time.ZoneOffset.UTC;
  84. import static java.util.Arrays.asList;
  85. import static java.util.Collections.emptySet;
  86. import static java.util.Collections.singletonList;
  87. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  88. import static org.assertj.core.api.Assertions.assertThat;
  89. import static org.mockito.Mockito.mock;
  90. import static org.mockito.Mockito.verify;
  91. import static org.mockito.Mockito.verifyZeroInteractions;
  92. import static org.mockito.Mockito.when;
  93. import static org.sonar.db.ce.CeTaskTypes.REPORT;
  94. import static org.sonar.db.component.ComponentTesting.newBranchDto;
  95. import static org.sonar.db.component.ComponentTesting.newDirectory;
  96. import static org.sonar.db.component.ComponentTesting.newFileDto;
  97. import static org.sonar.db.component.ComponentTesting.newModuleDto;
  98. import static org.sonar.db.component.ComponentTesting.newProjectCopy;
  99. import static org.sonar.db.component.ComponentTesting.newSubView;
  100. import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED;
  101. import static org.sonar.db.component.SnapshotDto.STATUS_UNPROCESSED;
  102. import static org.sonar.db.component.SnapshotTesting.newSnapshot;
  103. import static org.sonar.db.event.EventDto.CATEGORY_VERSION;
  104. import static org.sonar.db.webhook.WebhookDeliveryTesting.newDto;
  105. import static org.sonar.db.webhook.WebhookDeliveryTesting.selectAllDeliveryUuids;
  106. public class PurgeDaoTest {
  107. private static final String PROJECT_UUID = "P1";
  108. private System2 system2 = mock(System2.class);
  109. @Rule
  110. public DbTester db = DbTester.create(system2);
  111. @Rule
  112. public ExpectedException expectedException = ExpectedException.none();
  113. private DbClient dbClient = db.getDbClient();
  114. private DbSession dbSession = db.getSession();
  115. private PurgeDao underTest = db.getDbClient().purgeDao();
  116. @Test
  117. public void purge_failed_ce_tasks() {
  118. ComponentDto project = db.components().insertPrivateProject();
  119. SnapshotDto pastAnalysis = db.components().insertSnapshot(project, t -> t.setStatus(STATUS_PROCESSED).setLast(false));
  120. db.components().insertSnapshot(project, t -> t.setStatus(STATUS_UNPROCESSED).setLast(false));
  121. SnapshotDto lastAnalysis = db.components().insertSnapshot(project, t -> t.setStatus(STATUS_PROCESSED).setLast(true));
  122. underTest.purge(dbSession, newConfigurationWith30Days(project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
  123. dbSession.commit();
  124. assertThat(uuidsOfAnalysesOfRoot(project)).containsOnly(pastAnalysis.getUuid(), lastAnalysis.getUuid());
  125. }
  126. @Test
  127. public void purge_inactive_branches() {
  128. when(system2.now()).thenReturn(new Date().getTime());
  129. RuleDefinitionDto rule = db.rules().insert();
  130. ComponentDto project = db.components().insertPublicProject();
  131. ComponentDto branch1 = db.components().insertProjectBranch(project);
  132. ComponentDto branch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
  133. // branch with other components and issues, updated 31 days ago
  134. when(system2.now()).thenReturn(DateUtils.addDays(new Date(), -31).getTime());
  135. ComponentDto branch3 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
  136. ComponentDto module = db.components().insertComponent(newModuleDto(branch3));
  137. ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
  138. ComponentDto file = db.components().insertComponent(newFileDto(subModule));
  139. db.issues().insert(rule, branch3, file);
  140. db.issues().insert(rule, branch3, subModule);
  141. db.issues().insert(rule, branch3, module);
  142. underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
  143. dbSession.commit();
  144. assertThat(uuidsIn("components")).containsOnly(project.uuid(), branch1.uuid(), branch2.uuid());
  145. assertThat(uuidsIn("projects")).containsOnly(project.uuid());
  146. }
  147. @Test
  148. public void purge_inactive_pull_request() {
  149. when(system2.now()).thenReturn(new Date().getTime());
  150. RuleDefinitionDto rule = db.rules().insert();
  151. ComponentDto project = db.components().insertPublicProject();
  152. ComponentDto nonMainBranch = db.components().insertProjectBranch(project);
  153. ComponentDto recentPullRequest = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST));
  154. // pull request with other components and issues, updated 31 days ago
  155. when(system2.now()).thenReturn(DateUtils.addDays(new Date(), -31).getTime());
  156. ComponentDto pullRequest = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST));
  157. ComponentDto module = db.components().insertComponent(newModuleDto(pullRequest));
  158. ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
  159. ComponentDto file = db.components().insertComponent(newFileDto(subModule));
  160. db.issues().insert(rule, pullRequest, file);
  161. db.issues().insert(rule, pullRequest, subModule);
  162. db.issues().insert(rule, pullRequest, module);
  163. underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
  164. dbSession.commit();
  165. assertThat(uuidsIn("components")).containsOnly(project.uuid(), nonMainBranch.uuid(), recentPullRequest.uuid());
  166. assertThat(uuidsIn("projects")).containsOnly(project.uuid());
  167. }
  168. @Test
  169. public void purge_inactive_branches_when_analyzing_non_main_branch() {
  170. when(system2.now()).thenReturn(new Date().getTime());
  171. RuleDefinitionDto rule = db.rules().insert();
  172. ComponentDto project = db.components().insertPublicProject();
  173. ComponentDto nonMainBranch = db.components().insertProjectBranch(project);
  174. when(system2.now()).thenReturn(DateUtils.addDays(new Date(), -31).getTime());
  175. // branch updated 31 days ago
  176. ComponentDto branch1 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
  177. // branch with other components and issues, updated 31 days ago
  178. ComponentDto branch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST));
  179. ComponentDto file = db.components().insertComponent(newFileDto(branch2));
  180. db.issues().insert(rule, branch2, file);
  181. // back to present
  182. when(system2.now()).thenReturn(new Date().getTime());
  183. // analysing branch1
  184. underTest.purge(dbSession, newConfigurationWith30Days(system2, branch1.uuid(), branch1.getMainBranchProjectUuid()), PurgeListener.EMPTY, new PurgeProfiler());
  185. dbSession.commit();
  186. // branch1 wasn't deleted since it was being analyzed!
  187. assertThat(uuidsIn("components")).containsOnly(project.uuid(), nonMainBranch.uuid(), branch1.uuid());
  188. assertThat(uuidsIn("projects")).containsOnly(project.uuid());
  189. }
  190. @Test
  191. public void close_issues_clean_index_and_file_sources_of_disabled_components_specified_by_uuid_in_configuration() {
  192. RuleDefinitionDto rule = db.rules().insert();
  193. ComponentDto project = db.components().insertPublicProject();
  194. db.components().insertSnapshot(project);
  195. db.components().insertSnapshot(project);
  196. db.components().insertSnapshot(project, s -> s.setLast(false));
  197. ComponentDto module = db.components().insertComponent(newModuleDto(project).setEnabled(false));
  198. ComponentDto dir = db.components().insertComponent(newDirectory(module, "sub").setEnabled(false));
  199. ComponentDto srcFile = db.components().insertComponent(newFileDto(module, dir).setEnabled(false));
  200. ComponentDto testFile = db.components().insertComponent(newFileDto(module, dir).setEnabled(false));
  201. ComponentDto enabledFile = db.components().insertComponent(newFileDto(module, dir).setEnabled(true));
  202. IssueDto openOnFile = db.issues().insert(rule, project, srcFile, issue -> issue.setStatus("OPEN"));
  203. IssueDto confirmOnFile = db.issues().insert(rule, project, srcFile, issue -> issue.setStatus("CONFIRM"));
  204. IssueDto openOnDir = db.issues().insert(rule, project, dir, issue -> issue.setStatus("OPEN"));
  205. IssueDto confirmOnDir = db.issues().insert(rule, project, dir, issue -> issue.setStatus("CONFIRM"));
  206. IssueDto openOnEnabledComponent = db.issues().insert(rule, project, enabledFile, issue -> issue.setStatus("OPEN"));
  207. IssueDto confirmOnEnabledComponent = db.issues().insert(rule, project, enabledFile, issue -> issue.setStatus("CONFIRM"));
  208. assertThat(db.countSql("select count(*) from snapshots where purge_status = 1")).isEqualTo(0);
  209. assertThat(db.countSql("select count(*) from issues where status = 'CLOSED'")).isEqualTo(0);
  210. assertThat(db.countSql("select count(*) from issues where resolution = 'REMOVED'")).isEqualTo(0);
  211. db.fileSources().insertFileSource(srcFile);
  212. FileSourceDto nonSelectedFileSource = db.fileSources().insertFileSource(enabledFile);
  213. assertThat(db.countRowsOfTable("file_sources")).isEqualTo(2);
  214. MetricDto metric1 = db.measures().insertMetric();
  215. MetricDto metric2 = db.measures().insertMetric();
  216. LiveMeasureDto liveMeasureMetric1OnFile = db.measures().insertLiveMeasure(srcFile, metric1);
  217. LiveMeasureDto liveMeasureMetric2OnFile = db.measures().insertLiveMeasure(srcFile, metric2);
  218. LiveMeasureDto liveMeasureMetric1OnDir = db.measures().insertLiveMeasure(dir, metric1);
  219. LiveMeasureDto liveMeasureMetric2OnDir = db.measures().insertLiveMeasure(dir, metric2);
  220. LiveMeasureDto liveMeasureMetric1OnProject = db.measures().insertLiveMeasure(project, metric1);
  221. LiveMeasureDto liveMeasureMetric2OnProject = db.measures().insertLiveMeasure(project, metric2);
  222. LiveMeasureDto liveMeasureMetric1OnNonSelected = db.measures().insertLiveMeasure(enabledFile, metric1);
  223. LiveMeasureDto liveMeasureMetric2OnNonSelected = db.measures().insertLiveMeasure(enabledFile, metric2);
  224. assertThat(db.countRowsOfTable("live_measures")).isEqualTo(8);
  225. PurgeListener purgeListener = mock(PurgeListener.class);
  226. // back to present
  227. Set<String> selectedComponentUuids = ImmutableSet.of(module.uuid(), srcFile.uuid(), testFile.uuid());
  228. underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid(), selectedComponentUuids),
  229. purgeListener, new PurgeProfiler());
  230. dbSession.commit();
  231. verify(purgeListener).onComponentsDisabling(project.uuid(), selectedComponentUuids);
  232. verify(purgeListener).onComponentsDisabling(project.uuid(), ImmutableSet.of(dir.uuid()));
  233. // set purge_status=1 for non-last snapshot
  234. assertThat(db.countSql("select count(*) from snapshots where purge_status = 1")).isEqualTo(1);
  235. // close open issues of selected
  236. assertThat(db.countSql("select count(*) from issues where status = 'CLOSED'")).isEqualTo(4);
  237. for (IssueDto issue : Arrays.asList(openOnFile, confirmOnFile, openOnDir, confirmOnDir)) {
  238. assertThat(db.getDbClient().issueDao().selectOrFailByKey(dbSession, issue.getKey()))
  239. .extracting(IssueDto::getStatus, IssueDto::getResolution)
  240. .containsExactlyInAnyOrder("CLOSED", "REMOVED");
  241. }
  242. for (IssueDto issue : Arrays.asList(openOnEnabledComponent, confirmOnEnabledComponent)) {
  243. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, issue.getKey()).get())
  244. .extracting("status", "resolution")
  245. .containsExactlyInAnyOrder(issue.getStatus(), null);
  246. }
  247. // delete file sources of selected
  248. assertThat(db.countRowsOfTable("file_sources")).isEqualTo(1);
  249. assertThat(db.getDbClient().fileSourceDao().selectByFileUuid(dbSession, nonSelectedFileSource.getFileUuid())).isNotNull();
  250. // deletes live measure of selected
  251. assertThat(db.countRowsOfTable("live_measures")).isEqualTo(4);
  252. List<LiveMeasureDto> liveMeasureDtos = db.getDbClient().liveMeasureDao()
  253. .selectByComponentUuidsAndMetricIds(dbSession, ImmutableSet.of(srcFile.uuid(), dir.uuid(), project.uuid(), enabledFile.uuid()),
  254. ImmutableSet.of(metric1.getId(), metric2.getId()));
  255. assertThat(liveMeasureDtos)
  256. .extracting(LiveMeasureDto::getComponentUuid)
  257. .containsOnly(enabledFile.uuid(), project.uuid());
  258. assertThat(liveMeasureDtos)
  259. .extracting(LiveMeasureDto::getMetricId)
  260. .containsOnly(metric1.getId(), metric2.getId());
  261. }
  262. @Test
  263. public void shouldDeleteAnalyses() {
  264. ComponentDto project = db.components().insertPrivateProject();
  265. SnapshotDto analysis1 = db.components().insertSnapshot(project);
  266. SnapshotDto analysis2 = db.components().insertSnapshot(project);
  267. SnapshotDto analysis3 = db.components().insertSnapshot(project);
  268. ComponentDto otherProject = db.components().insertPrivateProject();
  269. SnapshotDto otherAnalysis1 = db.components().insertSnapshot(otherProject);
  270. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(idUuidPairOf(analysis1)));
  271. assertThat(uuidsIn("snapshots")).containsOnly(analysis2.getUuid(), analysis3.getUuid(), otherAnalysis1.getUuid());
  272. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(idUuidPairOf(analysis1), idUuidPairOf(analysis3), idUuidPairOf(otherAnalysis1)));
  273. assertThat(uuidsIn("snapshots")).containsOnly(analysis2.getUuid());
  274. }
  275. @Test
  276. public void deleteAnalyses_deletes_rows_in_events_and_event_component_changes() {
  277. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  278. dbClient.componentDao().insert(dbSession, project);
  279. SnapshotDto projectAnalysis1 = db.components().insertSnapshot(project);
  280. SnapshotDto projectAnalysis2 = db.components().insertSnapshot(project);
  281. SnapshotDto projectAnalysis3 = db.components().insertSnapshot(project);
  282. SnapshotDto projectAnalysis4 = db.components().insertSnapshot(project);
  283. EventDto projectEvent1 = db.events().insertEvent(projectAnalysis1);
  284. EventDto projectEvent2 = db.events().insertEvent(projectAnalysis2);
  285. EventDto projectEvent3 = db.events().insertEvent(projectAnalysis3);
  286. // note: projectAnalysis4 has no event
  287. ComponentDto referencedProjectA = db.components().insertPublicProject();
  288. ComponentDto referencedProjectB = db.components().insertPublicProject();
  289. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectA, null);
  290. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectB, null);
  291. BranchDto branchProjectA = newBranchDto(referencedProjectA);
  292. ComponentDto cptBranchProjectA = ComponentTesting.newBranchComponent(referencedProjectA, branchProjectA);
  293. db.events().insertEventComponentChanges(projectEvent2, projectAnalysis2, randomChangeCategory(), cptBranchProjectA, branchProjectA);
  294. // note: projectEvent3 has no component change
  295. // delete non existing analysis has no effect
  296. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(new IdUuidPair(3, "foo")));
  297. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  298. .containsOnly(projectAnalysis1.getUuid(), projectAnalysis2.getUuid());
  299. assertThat(db.countRowsOfTable("event_component_changes"))
  300. .isEqualTo(3);
  301. assertThat(uuidsIn("events"))
  302. .containsOnly(projectEvent1.getUuid(), projectEvent2.getUuid(), projectEvent3.getUuid());
  303. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(idUuidPairOf(projectAnalysis1)));
  304. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  305. .containsOnly(projectAnalysis2.getUuid());
  306. assertThat(db.countRowsOfTable("event_component_changes"))
  307. .isEqualTo(1);
  308. assertThat(uuidsIn("events"))
  309. .containsOnly(projectEvent2.getUuid(), projectEvent3.getUuid());
  310. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(idUuidPairOf(projectAnalysis4)));
  311. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  312. .containsOnly(projectAnalysis2.getUuid());
  313. assertThat(db.countRowsOfTable("event_component_changes"))
  314. .isEqualTo(1);
  315. assertThat(uuidsIn("events"))
  316. .containsOnly(projectEvent2.getUuid(), projectEvent3.getUuid());
  317. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(idUuidPairOf(projectAnalysis3)));
  318. assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
  319. .containsOnly(projectAnalysis2.getUuid());
  320. assertThat(db.countRowsOfTable("event_component_changes"))
  321. .isEqualTo(1);
  322. assertThat(uuidsIn("events"))
  323. .containsOnly(projectEvent2.getUuid());
  324. underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(idUuidPairOf(projectAnalysis2)));
  325. assertThat(db.countRowsOfTable("event_component_changes"))
  326. .isZero();
  327. assertThat(db.countRowsOfTable("events"))
  328. .isZero();
  329. }
  330. @Test
  331. public void selectPurgeableAnalyses() {
  332. SnapshotDto[] analyses = new SnapshotDto[] {
  333. newSnapshot()
  334. .setUuid("u1")
  335. .setComponentUuid(PROJECT_UUID)
  336. .setStatus(STATUS_PROCESSED)
  337. .setLast(true),
  338. // not processed -> exclude
  339. newSnapshot()
  340. .setUuid("u2")
  341. .setComponentUuid(PROJECT_UUID)
  342. .setStatus(STATUS_UNPROCESSED)
  343. .setLast(false),
  344. // on other resource -> exclude
  345. newSnapshot()
  346. .setUuid("u3")
  347. .setComponentUuid("uuid_222")
  348. .setStatus(STATUS_PROCESSED)
  349. .setLast(true),
  350. // without event -> select
  351. newSnapshot()
  352. .setUuid("u4")
  353. .setComponentUuid(PROJECT_UUID)
  354. .setStatus(STATUS_PROCESSED)
  355. .setLast(false),
  356. // with event -> select
  357. newSnapshot()
  358. .setUuid("u5")
  359. .setComponentUuid(PROJECT_UUID)
  360. .setStatus(STATUS_PROCESSED)
  361. .setLast(false)
  362. .setProjectVersion("V5")
  363. };
  364. db.components().insertSnapshots(analyses);
  365. db.events().insertEvent(EventTesting.newEvent(analyses[4])
  366. .setName("V5")
  367. .setCategory(CATEGORY_VERSION));
  368. List<PurgeableAnalysisDto> purgeableAnalyses = underTest.selectPurgeableAnalyses(PROJECT_UUID, dbSession);
  369. assertThat(purgeableAnalyses).hasSize(3);
  370. assertThat(getById(purgeableAnalyses, "u1").isLast()).isTrue();
  371. assertThat(getById(purgeableAnalyses, "u1").hasEvents()).isFalse();
  372. assertThat(getById(purgeableAnalyses, "u1").getVersion()).isNull();
  373. assertThat(getById(purgeableAnalyses, "u4").isLast()).isFalse();
  374. assertThat(getById(purgeableAnalyses, "u4").hasEvents()).isFalse();
  375. assertThat(getById(purgeableAnalyses, "u4").getVersion()).isNull();
  376. assertThat(getById(purgeableAnalyses, "u5").isLast()).isFalse();
  377. assertThat(getById(purgeableAnalyses, "u5").hasEvents()).isTrue();
  378. assertThat(getById(purgeableAnalyses, "u5").getVersion()).isEqualTo("V5");
  379. }
  380. @Test
  381. public void selectPurgeableAnalyses_does_not_return_the_baseline() {
  382. ComponentDto project1 = db.components().insertPublicProject(db.getDefaultOrganization(), "master");
  383. SnapshotDto analysis1 = db.components().insertSnapshot(newSnapshot()
  384. .setComponentUuid(project1.uuid())
  385. .setStatus(STATUS_PROCESSED)
  386. .setLast(false));
  387. dbClient.newCodePeriodDao().insert(dbSession,
  388. new NewCodePeriodDto()
  389. .setProjectUuid(project1.uuid())
  390. .setBranchUuid(project1.uuid())
  391. .setType(NewCodePeriodType.SPECIFIC_ANALYSIS)
  392. .setValue(analysis1.getUuid()));
  393. ComponentDto project2 = db.components().insertPrivateProject();
  394. SnapshotDto analysis2 = db.components().insertSnapshot(newSnapshot()
  395. .setComponentUuid(project2.uuid())
  396. .setStatus(STATUS_PROCESSED)
  397. .setLast(false));
  398. db.components().insertProjectBranch(project2);
  399. assertThat(underTest.selectPurgeableAnalyses(project1.uuid(), dbSession)).isEmpty();
  400. assertThat(underTest.selectPurgeableAnalyses(project2.uuid(), dbSession))
  401. .extracting(PurgeableAnalysisDto::getAnalysisUuid)
  402. .containsOnly(analysis2.getUuid());
  403. }
  404. @Test
  405. public void selectPurgeableAnalyses_does_not_return_the_baseline_of_specific_branch() {
  406. ComponentDto project = db.components().insertPublicProject(db.getDefaultOrganization(), "master");
  407. SnapshotDto analysisProject = db.components().insertSnapshot(newSnapshot()
  408. .setComponentUuid(project.uuid())
  409. .setStatus(STATUS_PROCESSED)
  410. .setLast(false));
  411. dbClient.newCodePeriodDao().insert(dbSession,
  412. new NewCodePeriodDto()
  413. .setProjectUuid(project.uuid())
  414. .setBranchUuid(project.uuid())
  415. .setType(NewCodePeriodType.SPECIFIC_ANALYSIS)
  416. .setValue(analysisProject.getUuid()));
  417. ComponentDto branch1 = db.components().insertProjectBranch(project);
  418. SnapshotDto analysisBranch1 = db.components().insertSnapshot(newSnapshot()
  419. .setComponentUuid(branch1.uuid())
  420. .setStatus(STATUS_PROCESSED)
  421. .setLast(false));
  422. ComponentDto branch2 = db.components().insertProjectBranch(project);
  423. SnapshotDto analysisBranch2 = db.components().insertSnapshot(newSnapshot()
  424. .setComponentUuid(branch2.uuid())
  425. .setStatus(STATUS_PROCESSED)
  426. .setLast(false));
  427. dbClient.newCodePeriodDao().insert(dbSession,
  428. new NewCodePeriodDto()
  429. .setProjectUuid(project.uuid())
  430. .setBranchUuid(branch2.uuid())
  431. .setType(NewCodePeriodType.SPECIFIC_ANALYSIS)
  432. .setValue(analysisBranch2.getUuid()));
  433. dbSession.commit();
  434. assertThat(underTest.selectPurgeableAnalyses(project.uuid(), dbSession))
  435. .isEmpty();
  436. assertThat(underTest.selectPurgeableAnalyses(branch1.uuid(), dbSession))
  437. .extracting(PurgeableAnalysisDto::getAnalysisUuid)
  438. .containsOnly(analysisBranch1.getUuid());
  439. assertThat(underTest.selectPurgeableAnalyses(branch2.uuid(), dbSession))
  440. .isEmpty();
  441. }
  442. @Test
  443. public void delete_project_and_associated_data() {
  444. RuleDefinitionDto rule = db.rules().insert();
  445. ComponentDto project = db.components().insertPrivateProject();
  446. ComponentDto module = db.components().insertComponent(newModuleDto(project));
  447. ComponentDto directory = db.components().insertComponent(newDirectory(module, "a/b"));
  448. ComponentDto file = db.components().insertComponent(newFileDto(directory));
  449. SnapshotDto analysis = db.components().insertSnapshot(project);
  450. IssueDto issue1 = db.issues().insert(rule, project, file);
  451. IssueChangeDto issueChange1 = db.issues().insertChange(issue1);
  452. IssueDto issue2 = db.issues().insert(rule, project, file);
  453. FileSourceDto fileSource = db.fileSources().insertFileSource(file);
  454. ComponentDto otherProject = db.components().insertPrivateProject();
  455. ComponentDto otherModule = db.components().insertComponent(newModuleDto(otherProject));
  456. ComponentDto otherDirectory = db.components().insertComponent(newDirectory(otherModule, "a/b"));
  457. ComponentDto otherFile = db.components().insertComponent(newFileDto(otherDirectory));
  458. SnapshotDto otherAnalysis = db.components().insertSnapshot(otherProject);
  459. IssueDto otherIssue1 = db.issues().insert(rule, otherProject, otherFile);
  460. IssueChangeDto otherIssueChange1 = db.issues().insertChange(otherIssue1);
  461. IssueDto otherIssue2 = db.issues().insert(rule, otherProject, otherFile);
  462. FileSourceDto otherFileSource = db.fileSources().insertFileSource(otherFile);
  463. underTest.deleteProject(dbSession, project.uuid());
  464. dbSession.commit();
  465. assertThat(uuidsIn("components")).containsOnly(otherProject.uuid(), otherModule.uuid(), otherDirectory.uuid(), otherFile.uuid());
  466. assertThat(uuidsIn("projects")).containsOnly(otherProject.uuid());
  467. assertThat(uuidsIn("snapshots")).containsOnly(otherAnalysis.getUuid());
  468. assertThat(uuidsIn("issues", "kee")).containsOnly(otherIssue1.getKey(), otherIssue2.getKey());
  469. assertThat(uuidsIn("issue_changes", "kee")).containsOnly(otherIssueChange1.getKey());
  470. assertThat(uuidsIn("file_sources", "file_uuid")).containsOnly(otherFileSource.getFileUuid());
  471. }
  472. @Test
  473. public void delete_webhooks_from_project() {
  474. OrganizationDto organization = db.organizations().insert();
  475. ProjectDto project1 = db.components().insertPrivateProjectDto(organization);
  476. WebhookDto webhook = db.webhooks().insertWebhook(project1);
  477. db.webhookDelivery().insert(webhook);
  478. ProjectDto projectNotToBeDeleted = db.components().insertPrivateProjectDto(organization);
  479. WebhookDto webhookNotDeleted = db.webhooks().insertWebhook(projectNotToBeDeleted);
  480. WebhookDeliveryLiteDto webhookDeliveryNotDeleted = db.webhookDelivery().insert(webhookNotDeleted);
  481. underTest.deleteProject(dbSession, project1.getUuid());
  482. assertThat(uuidsIn("webhooks")).containsOnly(webhookNotDeleted.getUuid());
  483. assertThat(uuidsIn("webhook_deliveries")).containsOnly(webhookDeliveryNotDeleted.getUuid());
  484. }
  485. private Stream<String> uuidsOfTable(String tableName) {
  486. return db.select("select uuid as \"UUID\" from " + tableName)
  487. .stream()
  488. .map(s -> (String) s.get("UUID"));
  489. }
  490. @Test
  491. public void delete_row_in_ce_activity_when_deleting_project() {
  492. ComponentDto projectToBeDeleted = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  493. ComponentDto anotherLivingProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  494. dbClient.componentDao().insert(dbSession, projectToBeDeleted, anotherLivingProject);
  495. // Insert 2 rows in CE_ACTIVITY : one for the project that will be deleted, and one on another project
  496. CeActivityDto toBeDeletedActivity = insertCeActivity(projectToBeDeleted);
  497. CeActivityDto notDeletedActivity = insertCeActivity(anotherLivingProject);
  498. dbSession.commit();
  499. underTest.deleteProject(dbSession, projectToBeDeleted.uuid());
  500. dbSession.commit();
  501. assertThat(uuidsOfTable("ce_activity"))
  502. .containsOnly(notDeletedActivity.getUuid())
  503. .hasSize(1);
  504. }
  505. @Test
  506. public void delete_row_in_ce_task_input_referring_to_a_row_in_ce_activity_when_deleting_project() {
  507. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  508. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  509. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  510. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  511. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  512. CeActivityDto projectTask = insertCeActivity(project);
  513. insertCeTaskInput(projectTask.getUuid());
  514. CeActivityDto branchTask = insertCeActivity(branch);
  515. insertCeTaskInput(branchTask.getUuid());
  516. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch);
  517. insertCeTaskInput(anotherBranchTask.getUuid());
  518. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject);
  519. insertCeTaskInput(anotherProjectTask.getUuid());
  520. insertCeTaskInput("non existing task");
  521. dbSession.commit();
  522. underTest.deleteProject(dbSession, branch.uuid());
  523. dbSession.commit();
  524. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  525. assertThat(taskUuidsIn("ce_task_input")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  526. underTest.deleteProject(dbSession, project.uuid());
  527. dbSession.commit();
  528. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  529. assertThat(taskUuidsIn("ce_task_input")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  530. }
  531. @Test
  532. public void delete_row_in_ce_scanner_context_referring_to_a_row_in_ce_activity_when_deleting_project() {
  533. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  534. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  535. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  536. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  537. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  538. CeActivityDto projectTask = insertCeActivity(project);
  539. insertCeScannerContext(projectTask.getUuid());
  540. CeActivityDto branchTask = insertCeActivity(branch);
  541. insertCeScannerContext(branchTask.getUuid());
  542. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch);
  543. insertCeScannerContext(anotherBranchTask.getUuid());
  544. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject);
  545. insertCeScannerContext(anotherProjectTask.getUuid());
  546. insertCeScannerContext("non existing task");
  547. dbSession.commit();
  548. underTest.deleteProject(dbSession, branch.uuid());
  549. dbSession.commit();
  550. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  551. assertThat(taskUuidsIn("ce_scanner_context")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  552. underTest.deleteProject(dbSession, project.uuid());
  553. dbSession.commit();
  554. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  555. assertThat(taskUuidsIn("ce_scanner_context")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  556. }
  557. @Test
  558. public void delete_row_in_ce_task_characteristics_referring_to_a_row_in_ce_activity_when_deleting_project() {
  559. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  560. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  561. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  562. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  563. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  564. CeActivityDto projectTask = insertCeActivity(project);
  565. insertCeTaskCharacteristics(projectTask.getUuid(), 3);
  566. CeActivityDto branchTask = insertCeActivity(branch);
  567. insertCeTaskCharacteristics(branchTask.getUuid(), 2);
  568. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch);
  569. insertCeTaskCharacteristics(anotherBranchTask.getUuid(), 6);
  570. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject);
  571. insertCeTaskCharacteristics(anotherProjectTask.getUuid(), 2);
  572. insertCeTaskCharacteristics("non existing task", 5);
  573. dbSession.commit();
  574. underTest.deleteProject(dbSession, branch.uuid());
  575. dbSession.commit();
  576. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  577. assertThat(taskUuidsIn("ce_task_characteristics")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  578. underTest.deleteProject(dbSession, project.uuid());
  579. dbSession.commit();
  580. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  581. assertThat(taskUuidsIn("ce_task_characteristics")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  582. }
  583. @Test
  584. public void delete_row_in_ce_task_message_referring_to_a_row_in_ce_activity_when_deleting_project() {
  585. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  586. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  587. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  588. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  589. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  590. CeActivityDto projectTask = insertCeActivity(project);
  591. insertCeTaskMessages(projectTask.getUuid(), 3);
  592. CeActivityDto branchTask = insertCeActivity(branch);
  593. insertCeTaskMessages(branchTask.getUuid(), 2);
  594. CeActivityDto anotherBranchTask = insertCeActivity(anotherBranch);
  595. insertCeTaskMessages(anotherBranchTask.getUuid(), 6);
  596. CeActivityDto anotherProjectTask = insertCeActivity(anotherProject);
  597. insertCeTaskMessages(anotherProjectTask.getUuid(), 2);
  598. insertCeTaskMessages("non existing task", 5);
  599. dbSession.commit();
  600. underTest.deleteProject(dbSession, branch.uuid());
  601. dbSession.commit();
  602. assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  603. assertThat(taskUuidsIn("ce_task_message")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  604. underTest.deleteProject(dbSession, project.uuid());
  605. dbSession.commit();
  606. assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid());
  607. assertThat(taskUuidsIn("ce_task_message")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  608. }
  609. @Test
  610. public void delete_tasks_in_ce_queue_when_deleting_project() {
  611. ComponentDto projectToBeDeleted = db.components().insertPrivateProject();
  612. ComponentDto anotherLivingProject = db.components().insertPrivateProject();
  613. // Insert 3 rows in CE_QUEUE: two for the project that will be deleted (in order to check that status
  614. // is not involved in deletion), and one on another project
  615. dbClient.ceQueueDao().insert(dbSession, createCeQueue(projectToBeDeleted, Status.PENDING));
  616. dbClient.ceQueueDao().insert(dbSession, createCeQueue(projectToBeDeleted, Status.IN_PROGRESS));
  617. dbClient.ceQueueDao().insert(dbSession, createCeQueue(anotherLivingProject, Status.PENDING));
  618. dbSession.commit();
  619. underTest.deleteProject(dbSession, projectToBeDeleted.uuid());
  620. dbSession.commit();
  621. assertThat(db.countRowsOfTable("ce_queue")).isEqualTo(1);
  622. assertThat(db.countSql("select count(*) from ce_queue where main_component_uuid='" + projectToBeDeleted.uuid() + "'")).isEqualTo(0);
  623. }
  624. @Test
  625. public void delete_row_in_ce_task_input_referring_to_a_row_in_ce_queue_when_deleting_project() {
  626. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  627. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  628. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  629. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  630. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  631. CeQueueDto projectTask = insertCeQueue(project);
  632. insertCeTaskInput(projectTask.getUuid());
  633. CeQueueDto branchTask = insertCeQueue(branch);
  634. insertCeTaskInput(branchTask.getUuid());
  635. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch);
  636. insertCeTaskInput(anotherBranchTask.getUuid());
  637. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  638. insertCeTaskInput(anotherProjectTask.getUuid());
  639. insertCeTaskInput("non existing task");
  640. dbSession.commit();
  641. underTest.deleteProject(dbSession, branch.uuid());
  642. dbSession.commit();
  643. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  644. assertThat(taskUuidsIn("ce_task_input")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  645. underTest.deleteProject(dbSession, project.uuid());
  646. dbSession.commit();
  647. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  648. assertThat(taskUuidsIn("ce_task_input")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  649. }
  650. @Test
  651. public void delete_row_in_ce_scanner_context_referring_to_a_row_in_ce_queue_when_deleting_project() {
  652. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  653. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  654. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  655. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  656. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  657. CeQueueDto projectTask = insertCeQueue(project);
  658. insertCeScannerContext(projectTask.getUuid());
  659. CeQueueDto branchTask = insertCeQueue(branch);
  660. insertCeScannerContext(branchTask.getUuid());
  661. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch);
  662. insertCeScannerContext(anotherBranchTask.getUuid());
  663. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  664. insertCeScannerContext(anotherProjectTask.getUuid());
  665. insertCeScannerContext("non existing task");
  666. dbSession.commit();
  667. underTest.deleteProject(dbSession, branch.uuid());
  668. dbSession.commit();
  669. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  670. assertThat(taskUuidsIn("ce_scanner_context"))
  671. .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  672. underTest.deleteProject(dbSession, project.uuid());
  673. dbSession.commit();
  674. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  675. assertThat(taskUuidsIn("ce_scanner_context")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  676. }
  677. @Test
  678. public void delete_row_in_ce_task_characteristics_referring_to_a_row_in_ce_queue_when_deleting_project() {
  679. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  680. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  681. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  682. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  683. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  684. CeQueueDto projectTask = insertCeQueue(project);
  685. insertCeTaskCharacteristics(projectTask.getUuid(), 3);
  686. CeQueueDto branchTask = insertCeQueue(branch);
  687. insertCeTaskCharacteristics(branchTask.getUuid(), 1);
  688. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch);
  689. insertCeTaskCharacteristics(anotherBranchTask.getUuid(), 5);
  690. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  691. insertCeTaskCharacteristics(anotherProjectTask.getUuid(), 2);
  692. insertCeTaskCharacteristics("non existing task", 5);
  693. dbSession.commit();
  694. underTest.deleteProject(dbSession, branch.uuid());
  695. dbSession.commit();
  696. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  697. assertThat(taskUuidsIn("ce_task_characteristics"))
  698. .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  699. underTest.deleteProject(dbSession, project.uuid());
  700. dbSession.commit();
  701. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  702. assertThat(taskUuidsIn("ce_task_characteristics")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  703. }
  704. @Test
  705. public void delete_row_in_ce_task_message_referring_to_a_row_in_ce_queue_when_deleting_project() {
  706. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  707. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  708. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  709. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  710. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  711. CeQueueDto projectTask = insertCeQueue(project);
  712. insertCeTaskMessages(projectTask.getUuid(), 3);
  713. CeQueueDto branchTask = insertCeQueue(branch);
  714. insertCeTaskMessages(branchTask.getUuid(), 1);
  715. CeQueueDto anotherBranchTask = insertCeQueue(anotherBranch);
  716. insertCeTaskMessages(anotherBranchTask.getUuid(), 5);
  717. CeQueueDto anotherProjectTask = insertCeQueue(anotherProject);
  718. insertCeTaskMessages(anotherProjectTask.getUuid(), 2);
  719. insertCeTaskMessages("non existing task", 5);
  720. dbSession.commit();
  721. underTest.deleteProject(dbSession, branch.uuid());
  722. dbSession.commit();
  723. assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid());
  724. assertThat(taskUuidsIn("ce_task_message"))
  725. .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task");
  726. underTest.deleteProject(dbSession, project.uuid());
  727. dbSession.commit();
  728. assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid());
  729. assertThat(taskUuidsIn("ce_task_message")).containsOnly(anotherProjectTask.getUuid(), "non existing task");
  730. }
  731. @Test
  732. public void delete_row_in_events_and_event_component_changes_when_deleting_project() {
  733. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  734. ComponentDto branch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  735. ComponentDto anotherBranch = ComponentTesting.newBranchComponent(project, newBranchDto(project));
  736. ComponentDto anotherProject = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  737. dbClient.componentDao().insert(dbSession, project, branch, anotherBranch, anotherProject);
  738. SnapshotDto projectAnalysis1 = db.components().insertSnapshot(project);
  739. SnapshotDto projectAnalysis2 = db.components().insertSnapshot(project);
  740. EventDto projectEvent1 = db.events().insertEvent(projectAnalysis1);
  741. EventDto projectEvent2 = db.events().insertEvent(projectAnalysis2);
  742. EventDto projectEvent3 = db.events().insertEvent(db.components().insertSnapshot(project));
  743. SnapshotDto branchAnalysis1 = db.components().insertSnapshot(branch);
  744. SnapshotDto branchAnalysis2 = db.components().insertSnapshot(branch);
  745. EventDto branchEvent1 = db.events().insertEvent(branchAnalysis1);
  746. EventDto branchEvent2 = db.events().insertEvent(branchAnalysis2);
  747. SnapshotDto anotherBranchAnalysis = db.components().insertSnapshot(anotherBranch);
  748. EventDto anotherBranchEvent = db.events().insertEvent(anotherBranchAnalysis);
  749. SnapshotDto anotherProjectAnalysis = db.components().insertSnapshot(anotherProject);
  750. EventDto anotherProjectEvent = db.events().insertEvent(anotherProjectAnalysis);
  751. ComponentDto referencedProjectA = db.components().insertPublicProject();
  752. ComponentDto referencedProjectB = db.components().insertPublicProject();
  753. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectA, null);
  754. db.events().insertEventComponentChanges(projectEvent1, projectAnalysis1, randomChangeCategory(), referencedProjectB, null);
  755. BranchDto branchProjectA = newBranchDto(referencedProjectA);
  756. ComponentDto cptBranchProjectA = ComponentTesting.newBranchComponent(referencedProjectA, branchProjectA);
  757. db.events().insertEventComponentChanges(projectEvent2, projectAnalysis2, randomChangeCategory(), cptBranchProjectA, branchProjectA);
  758. // note: projectEvent3 has no component change
  759. db.events().insertEventComponentChanges(branchEvent1, branchAnalysis1, randomChangeCategory(), referencedProjectB, null);
  760. db.events().insertEventComponentChanges(branchEvent2, branchAnalysis2, randomChangeCategory(), cptBranchProjectA, branchProjectA);
  761. db.events().insertEventComponentChanges(anotherBranchEvent, anotherBranchAnalysis, randomChangeCategory(), referencedProjectB, null);
  762. db.events().insertEventComponentChanges(anotherProjectEvent, anotherProjectAnalysis, randomChangeCategory(), referencedProjectB, null);
  763. // deleting referenced project does not delete any data
  764. underTest.deleteProject(dbSession, referencedProjectA.uuid());
  765. assertThat(db.countRowsOfTable("event_component_changes"))
  766. .isEqualTo(7);
  767. assertThat(db.countRowsOfTable("events"))
  768. .isEqualTo(7);
  769. underTest.deleteProject(dbSession, branch.uuid());
  770. assertThat(uuidsIn("event_component_changes", "event_component_uuid"))
  771. .containsOnly(project.uuid(), anotherBranch.uuid(), anotherProject.uuid());
  772. assertThat(db.countRowsOfTable("event_component_changes"))
  773. .isEqualTo(5);
  774. assertThat(uuidsIn("events"))
  775. .containsOnly(projectEvent1.getUuid(), projectEvent2.getUuid(), projectEvent3.getUuid(), anotherBranchEvent.getUuid(), anotherProjectEvent.getUuid());
  776. underTest.deleteProject(dbSession, project.uuid());
  777. assertThat(uuidsIn("event_component_changes", "event_component_uuid"))
  778. .containsOnly(anotherBranch.uuid(), anotherProject.uuid());
  779. assertThat(db.countRowsOfTable("event_component_changes"))
  780. .isEqualTo(2);
  781. assertThat(uuidsIn("events"))
  782. .containsOnly(anotherBranchEvent.getUuid(), anotherProjectEvent.getUuid());
  783. }
  784. private static EventComponentChangeDto.ChangeCategory randomChangeCategory() {
  785. return EventComponentChangeDto.ChangeCategory.values()[new Random().nextInt(EventComponentChangeDto.ChangeCategory.values().length)];
  786. }
  787. private ComponentDto insertProjectWithBranchAndRelatedData() {
  788. RuleDefinitionDto rule = db.rules().insert();
  789. ComponentDto project = db.components().insertPublicProject();
  790. ComponentDto branch = db.components().insertProjectBranch(project);
  791. ComponentDto module = db.components().insertComponent(newModuleDto(branch));
  792. ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
  793. ComponentDto file = db.components().insertComponent(newFileDto(subModule));
  794. db.issues().insert(rule, branch, file);
  795. db.issues().insert(rule, branch, subModule);
  796. db.issues().insert(rule, branch, module);
  797. return project;
  798. }
  799. @Test
  800. public void delete_branch_content_when_deleting_project() {
  801. ComponentDto anotherLivingProject = insertProjectWithBranchAndRelatedData();
  802. int projectEntryCount = db.countRowsOfTable("components");
  803. int issueCount = db.countRowsOfTable("issues");
  804. int branchCount = db.countRowsOfTable("project_branches");
  805. ComponentDto projectToDelete = insertProjectWithBranchAndRelatedData();
  806. assertThat(db.countRowsOfTable("components")).isGreaterThan(projectEntryCount);
  807. assertThat(db.countRowsOfTable("issues")).isGreaterThan(issueCount);
  808. assertThat(db.countRowsOfTable("project_branches")).isGreaterThan(branchCount);
  809. underTest.deleteProject(dbSession, projectToDelete.uuid());
  810. dbSession.commit();
  811. assertThat(db.countRowsOfTable("components")).isEqualTo(projectEntryCount);
  812. assertThat(db.countRowsOfTable("issues")).isEqualTo(issueCount);
  813. assertThat(db.countRowsOfTable("project_branches")).isEqualTo(branchCount);
  814. }
  815. @Test
  816. public void delete_view_and_child() {
  817. ComponentDto project = db.components().insertPrivateProject();
  818. ComponentDto view = db.components().insertView();
  819. ComponentDto subView = db.components().insertComponent(newSubView(view));
  820. ComponentDto projectCopy = db.components().insertComponent(newProjectCopy(project, subView));
  821. ComponentDto otherView = db.components().insertView();
  822. ComponentDto otherSubView = db.components().insertComponent(newSubView(otherView));
  823. ComponentDto otherProjectCopy = db.components().insertComponent(newProjectCopy(project, otherSubView));
  824. underTest.deleteProject(dbSession, view.uuid());
  825. dbSession.commit();
  826. assertThat(uuidsIn("components"))
  827. .containsOnly(project.uuid(), otherView.uuid(), otherSubView.uuid(), otherProjectCopy.uuid());
  828. }
  829. @Test
  830. public void deleteProject_fails_with_IAE_if_specified_component_is_module() {
  831. ComponentDto privateProject = db.components().insertPrivateProject();
  832. ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(privateProject));
  833. expectedException.expect(IllegalArgumentException.class);
  834. expectedException.expectMessage("Couldn't find root component with uuid " + module.uuid());
  835. underTest.deleteProject(dbSession, module.uuid());
  836. }
  837. @Test
  838. public void deleteProject_fails_with_IAE_if_specified_component_is_directory() {
  839. ComponentDto privateProject = db.components().insertPrivateProject();
  840. ComponentDto directory = db.components().insertComponent(newDirectory(privateProject, "A/B"));
  841. expectedException.expect(IllegalArgumentException.class);
  842. expectedException.expectMessage("Couldn't find root component with uuid " + directory.uuid());
  843. underTest.deleteProject(dbSession, directory.uuid());
  844. }
  845. @Test
  846. public void deleteProject_fails_with_IAE_if_specified_component_is_file() {
  847. ComponentDto privateProject = db.components().insertPrivateProject();
  848. ComponentDto file = db.components().insertComponent(newFileDto(privateProject));
  849. expectedException.expect(IllegalArgumentException.class);
  850. expectedException.expectMessage("Couldn't find root component with uuid " + file.uuid());
  851. underTest.deleteProject(dbSession, file.uuid());
  852. }
  853. @Test
  854. public void deleteProject_fails_with_IAE_if_specified_component_is_subview() {
  855. ComponentDto view = db.components().insertView();
  856. ComponentDto subview = db.components().insertComponent(newSubView(view));
  857. expectedException.expect(IllegalArgumentException.class);
  858. expectedException.expectMessage("Couldn't find root component with uuid " + subview.uuid());
  859. underTest.deleteProject(dbSession, subview.uuid());
  860. }
  861. @Test
  862. public void should_delete_old_closed_issues() {
  863. RuleDefinitionDto rule = db.rules().insert();
  864. ComponentDto project = db.components().insertPublicProject();
  865. ComponentDto module = db.components().insertComponent(newModuleDto(project));
  866. ComponentDto file = db.components().insertComponent(newFileDto(module));
  867. IssueDto oldClosed = db.issues().insert(rule, project, file, issue -> {
  868. issue.setStatus("CLOSED");
  869. issue.setIssueCloseDate(DateUtils.addDays(new Date(), -31));
  870. });
  871. IssueDto notOldEnoughClosed = db.issues().insert(rule, project, file, issue -> {
  872. issue.setStatus("CLOSED");
  873. issue.setIssueCloseDate(new Date());
  874. });
  875. IssueDto notClosed = db.issues().insert(rule, project, file);
  876. when(system2.now()).thenReturn(new Date().getTime());
  877. underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
  878. dbSession.commit();
  879. // old closed got deleted
  880. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, oldClosed.getKey())).isEmpty();
  881. // others remain
  882. assertThat(db.countRowsOfTable("issues")).isEqualTo(2);
  883. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, notOldEnoughClosed.getKey())).isNotEmpty();
  884. assertThat(db.getDbClient().issueDao().selectByKey(dbSession, notClosed.getKey())).isNotEmpty();
  885. }
  886. @Test
  887. public void delete_disabled_components_without_issues() {
  888. ComponentDto project = db.components().insertPublicProject(p -> p.setEnabled(true));
  889. ComponentDto enabledFileWithIssues = db.components().insertComponent(newFileDto(project).setEnabled(true));
  890. ComponentDto disabledFileWithIssues = db.components().insertComponent(newFileDto(project).setEnabled(false));
  891. ComponentDto enabledFileWithoutIssues = db.components().insertComponent(newFileDto(project).setEnabled(true));
  892. ComponentDto disabledFileWithoutIssues = db.components().insertComponent(newFileDto(project).setEnabled(false));
  893. RuleDefinitionDto rule = db.rules().insert();
  894. IssueDto closed1 = db.issues().insert(rule, project, enabledFileWithIssues, issue -> {
  895. issue.setStatus("CLOSED");
  896. issue.setResolution(Issue.RESOLUTION_FIXED);
  897. issue.setIssueCloseDate(new Date());
  898. });
  899. IssueDto closed2 = db.issues().insert(rule, project, disabledFileWithIssues, issue -> {
  900. issue.setStatus("CLOSED");
  901. issue.setResolution(Issue.RESOLUTION_FIXED);
  902. issue.setIssueCloseDate(new Date());
  903. });
  904. PurgeListener purgeListener = mock(PurgeListener.class);
  905. Set<String> disabledComponentUuids = ImmutableSet.of(disabledFileWithIssues.uuid(), disabledFileWithoutIssues.uuid());
  906. underTest.purge(dbSession,
  907. newConfigurationWith30Days(System2.INSTANCE, project.uuid(), project.uuid(), disabledComponentUuids),
  908. purgeListener, new PurgeProfiler());
  909. assertThat(db.getDbClient().componentDao().selectByProjectUuid(project.uuid(), dbSession))
  910. .extracting("uuid")
  911. .containsOnly(project.uuid(), enabledFileWithIssues.uuid(), disabledFileWithIssues.uuid(),
  912. enabledFileWithoutIssues.uuid());
  913. verify(purgeListener).onComponentsDisabling(project.uuid(), disabledComponentUuids);
  914. }
  915. @Test
  916. public void delete_ce_analysis_older_than_180_and_scanner_context_older_than_40_days_of_specified_project_when_purging_project() {
  917. LocalDateTime now = LocalDateTime.now();
  918. ComponentDto project1 = db.components().insertPublicProject();
  919. Consumer<CeQueueDto> belongsToProject1 = t -> t.setMainComponentUuid(project1.uuid()).setComponentUuid(project1.uuid());
  920. ComponentDto project2 = db.components().insertPublicProject();
  921. Consumer<CeQueueDto> belongsToProject2 = t -> t.setMainComponentUuid(project2.uuid()).setComponentUuid(project2.uuid());
  922. insertCeActivityAndChildDataWithDate("VERY_OLD_1", now.minusDays(180).minusMonths(10), belongsToProject1);
  923. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_1", now.minusDays(180).minusDays(1), belongsToProject1);
  924. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_1", now.minusDays(180), belongsToProject1);
  925. insertCeActivityAndChildDataWithDate("RECENT_1", now.minusDays(1), belongsToProject1);
  926. insertCeActivityAndChildDataWithDate("VERY_OLD_2", now.minusDays(180).minusMonths(10), belongsToProject2);
  927. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_2", now.minusDays(180).minusDays(1), belongsToProject2);
  928. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_2", now.minusDays(180), belongsToProject2);
  929. insertCeActivityAndChildDataWithDate("RECENT_2", now.minusDays(1), belongsToProject2);
  930. when(system2.now()).thenReturn(now.toInstant(ZoneOffset.UTC).toEpochMilli());
  931. underTest.purge(db.getSession(), newConfigurationWith30Days(System2.INSTANCE, project1.uuid(), project1.uuid()),
  932. PurgeListener.EMPTY, new PurgeProfiler());
  933. assertThat(selectActivity("VERY_OLD_1")).isEmpty();
  934. assertThat(selectTaskInput("VERY_OLD_1")).isEmpty();
  935. assertThat(selectTaskCharacteristic("VERY_OLD_1")).hasSize(0);
  936. assertThat(scannerContextExists("VERY_OLD_1")).isFalse();
  937. assertThat(selectActivity("VERY_OLD_2")).isNotEmpty();
  938. assertThat(selectTaskInput("VERY_OLD_2")).isNotEmpty();
  939. assertThat(selectTaskCharacteristic("VERY_OLD_2")).hasSize(1);
  940. assertThat(scannerContextExists("VERY_OLD_2")).isTrue();
  941. assertThat(selectActivity("JUST_OLD_ENOUGH_1")).isEmpty();
  942. assertThat(selectTaskInput("JUST_OLD_ENOUGH_1")).isEmpty();
  943. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_1")).hasSize(0);
  944. assertThat(scannerContextExists("JUST_OLD_ENOUGH_1")).isFalse();
  945. assertThat(selectActivity("JUST_OLD_ENOUGH_2")).isNotEmpty();
  946. assertThat(selectTaskInput("JUST_OLD_ENOUGH_2")).isNotEmpty();
  947. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_2")).hasSize(1);
  948. assertThat(scannerContextExists("JUST_OLD_ENOUGH_2")).isTrue();
  949. assertThat(selectActivity("NOT_OLD_ENOUGH_1")).isNotEmpty();
  950. assertThat(selectTaskInput("NOT_OLD_ENOUGH_1")).isNotEmpty();
  951. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_1")).hasSize(1);
  952. assertThat(scannerContextExists("NOT_OLD_ENOUGH_1")).isFalse(); // because more than 4 weeks old
  953. assertThat(selectActivity("NOT_OLD_ENOUGH_2")).isNotEmpty();
  954. assertThat(selectTaskInput("NOT_OLD_ENOUGH_2")).isNotEmpty();
  955. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_2")).hasSize(1);
  956. assertThat(scannerContextExists("NOT_OLD_ENOUGH_2")).isTrue();
  957. assertThat(selectActivity("RECENT_1")).isNotEmpty();
  958. assertThat(selectTaskInput("RECENT_1")).isNotEmpty();
  959. assertThat(selectTaskCharacteristic("RECENT_1")).hasSize(1);
  960. assertThat(scannerContextExists("RECENT_1")).isTrue();
  961. assertThat(selectActivity("RECENT_2")).isNotEmpty();
  962. assertThat(selectTaskInput("RECENT_2")).isNotEmpty();
  963. assertThat(selectTaskCharacteristic("RECENT_2")).hasSize(1);
  964. assertThat(scannerContextExists("RECENT_2")).isTrue();
  965. }
  966. @Test
  967. public void delete_ce_analysis_older_than_180_and_scanner_context_older_than_40_days_of_project_and_branches_when_purging_project() {
  968. LocalDateTime now = LocalDateTime.now();
  969. ComponentDto project1 = db.components().insertPublicProject();
  970. ComponentDto branch1 = db.components().insertProjectBranch(project1, b -> b.setExcludeFromPurge(true));
  971. Consumer<CeQueueDto> belongsToProject1 = t -> t.setMainComponentUuid(project1.uuid()).setComponentUuid(project1.uuid());
  972. Consumer<CeQueueDto> belongsToBranch1 = t -> t.setMainComponentUuid(project1.uuid()).setComponentUuid(branch1.uuid());
  973. insertCeActivityAndChildDataWithDate("VERY_OLD_1", now.minusDays(180).minusMonths(10), belongsToProject1);
  974. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_1", now.minusDays(180).minusDays(1), belongsToProject1);
  975. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_1", now.minusDays(180), belongsToProject1);
  976. insertCeActivityAndChildDataWithDate("RECENT_1", now.minusDays(1), belongsToProject1);
  977. insertCeActivityAndChildDataWithDate("VERY_OLD_2", now.minusDays(180).minusMonths(10), belongsToBranch1);
  978. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_2", now.minusDays(180).minusDays(1), belongsToBranch1);
  979. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_2", now.minusDays(180), belongsToBranch1);
  980. insertCeActivityAndChildDataWithDate("RECENT_2", now.minusDays(1), belongsToBranch1);
  981. when(system2.now()).thenReturn(now.toInstant(ZoneOffset.UTC).toEpochMilli());
  982. underTest.purge(db.getSession(), newConfigurationWith30Days(System2.INSTANCE, project1.uuid(), project1.uuid()),
  983. PurgeListener.EMPTY, new PurgeProfiler());
  984. assertThat(selectActivity("VERY_OLD_1")).isEmpty();
  985. assertThat(selectTaskInput("VERY_OLD_1")).isEmpty();
  986. assertThat(selectTaskCharacteristic("VERY_OLD_1")).hasSize(0);
  987. assertThat(scannerContextExists("VERY_OLD_1")).isFalse();
  988. assertThat(selectActivity("VERY_OLD_2")).isEmpty();
  989. assertThat(selectTaskInput("VERY_OLD_2")).isEmpty();
  990. assertThat(selectTaskCharacteristic("VERY_OLD_2")).isEmpty();
  991. assertThat(scannerContextExists("VERY_OLD_2")).isFalse();
  992. assertThat(selectActivity("JUST_OLD_ENOUGH_1")).isEmpty();
  993. assertThat(selectTaskInput("JUST_OLD_ENOUGH_1")).isEmpty();
  994. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_1")).hasSize(0);
  995. assertThat(scannerContextExists("JUST_OLD_ENOUGH_1")).isFalse();
  996. assertThat(selectActivity("JUST_OLD_ENOUGH_2")).isEmpty();
  997. assertThat(selectTaskInput("JUST_OLD_ENOUGH_2")).isEmpty();
  998. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_2")).isEmpty();
  999. assertThat(scannerContextExists("JUST_OLD_ENOUGH_2")).isFalse();
  1000. assertThat(selectActivity("NOT_OLD_ENOUGH_1")).isNotEmpty();
  1001. assertThat(selectTaskInput("NOT_OLD_ENOUGH_1")).isNotEmpty();
  1002. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_1")).hasSize(1);
  1003. assertThat(scannerContextExists("NOT_OLD_ENOUGH_1")).isFalse(); // because more than 4 weeks old
  1004. assertThat(selectActivity("NOT_OLD_ENOUGH_2")).isNotEmpty();
  1005. assertThat(selectTaskInput("NOT_OLD_ENOUGH_2")).isNotEmpty();
  1006. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_2")).hasSize(1);
  1007. assertThat(scannerContextExists("NOT_OLD_ENOUGH_2")).isFalse(); // because more than 4 weeks old
  1008. assertThat(selectActivity("RECENT_1")).isNotEmpty();
  1009. assertThat(selectTaskInput("RECENT_1")).isNotEmpty();
  1010. assertThat(selectTaskCharacteristic("RECENT_1")).hasSize(1);
  1011. assertThat(scannerContextExists("RECENT_1")).isTrue();
  1012. assertThat(selectActivity("RECENT_2")).isNotEmpty();
  1013. assertThat(selectTaskInput("RECENT_2")).isNotEmpty();
  1014. assertThat(selectTaskCharacteristic("RECENT_2")).hasSize(1);
  1015. assertThat(scannerContextExists("RECENT_2")).isTrue();
  1016. }
  1017. @Test
  1018. public void delete_ce_analysis_of_branch_older_than_180_and_scanner_context_older_than_40_days_when_purging_branch() {
  1019. LocalDateTime now = LocalDateTime.now();
  1020. ComponentDto project1 = db.components().insertPublicProject();
  1021. ComponentDto branch1 = db.components().insertProjectBranch(project1);
  1022. Consumer<CeQueueDto> belongsToProject1 = t -> t.setMainComponentUuid(project1.uuid()).setComponentUuid(project1.uuid());
  1023. Consumer<CeQueueDto> belongsToBranch1 = t -> t.setMainComponentUuid(project1.uuid()).setComponentUuid(branch1.uuid());
  1024. insertCeActivityAndChildDataWithDate("VERY_OLD_1", now.minusDays(180).minusMonths(10), belongsToProject1);
  1025. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_1", now.minusDays(180).minusDays(1), belongsToProject1);
  1026. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_1", now.minusDays(180), belongsToProject1);
  1027. insertCeActivityAndChildDataWithDate("RECENT_1", now.minusDays(1), belongsToProject1);
  1028. insertCeActivityAndChildDataWithDate("VERY_OLD_2", now.minusDays(180).minusMonths(10), belongsToBranch1);
  1029. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH_2", now.minusDays(180).minusDays(1), belongsToBranch1);
  1030. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH_2", now.minusDays(180), belongsToBranch1);
  1031. insertCeActivityAndChildDataWithDate("RECENT_2", now.minusDays(1), belongsToBranch1);
  1032. when(system2.now()).thenReturn(now.toInstant(ZoneOffset.UTC).toEpochMilli());
  1033. underTest.purge(db.getSession(), newConfigurationWith30Days(System2.INSTANCE, branch1.uuid(), branch1.uuid()),
  1034. PurgeListener.EMPTY, new PurgeProfiler());
  1035. assertThat(selectActivity("VERY_OLD_1")).isNotEmpty();
  1036. assertThat(selectTaskInput("VERY_OLD_1")).isNotEmpty();
  1037. assertThat(selectTaskCharacteristic("VERY_OLD_1")).hasSize(1);
  1038. assertThat(scannerContextExists("VERY_OLD_1")).isTrue();
  1039. assertThat(selectActivity("VERY_OLD_2")).isEmpty();
  1040. assertThat(selectTaskInput("VERY_OLD_2")).isEmpty();
  1041. assertThat(selectTaskCharacteristic("VERY_OLD_2")).isEmpty();
  1042. assertThat(scannerContextExists("VERY_OLD_2")).isFalse();
  1043. assertThat(selectActivity("JUST_OLD_ENOUGH_1")).isNotEmpty();
  1044. assertThat(selectTaskInput("JUST_OLD_ENOUGH_1")).isNotEmpty();
  1045. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_1")).hasSize(1);
  1046. assertThat(scannerContextExists("JUST_OLD_ENOUGH_1")).isTrue();
  1047. assertThat(selectActivity("JUST_OLD_ENOUGH_2")).isEmpty();
  1048. assertThat(selectTaskInput("JUST_OLD_ENOUGH_2")).isEmpty();
  1049. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH_2")).isEmpty();
  1050. assertThat(scannerContextExists("JUST_OLD_ENOUGH_2")).isFalse();
  1051. assertThat(selectActivity("NOT_OLD_ENOUGH_1")).isNotEmpty();
  1052. assertThat(selectTaskInput("NOT_OLD_ENOUGH_1")).isNotEmpty();
  1053. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_1")).hasSize(1);
  1054. assertThat(scannerContextExists("NOT_OLD_ENOUGH_1")).isTrue();
  1055. assertThat(selectActivity("NOT_OLD_ENOUGH_2")).isNotEmpty();
  1056. assertThat(selectTaskInput("NOT_OLD_ENOUGH_2")).isNotEmpty();
  1057. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH_2")).hasSize(1);
  1058. assertThat(scannerContextExists("NOT_OLD_ENOUGH_2")).isFalse(); // because more than 4 weeks old
  1059. assertThat(selectActivity("RECENT_1")).isNotEmpty();
  1060. assertThat(selectTaskInput("RECENT_1")).isNotEmpty();
  1061. assertThat(selectTaskCharacteristic("RECENT_1")).hasSize(1);
  1062. assertThat(scannerContextExists("RECENT_1")).isTrue();
  1063. assertThat(selectActivity("RECENT_2")).isNotEmpty();
  1064. assertThat(selectTaskInput("RECENT_2")).isNotEmpty();
  1065. assertThat(selectTaskCharacteristic("RECENT_2")).hasSize(1);
  1066. assertThat(scannerContextExists("RECENT_2")).isTrue();
  1067. }
  1068. @Test
  1069. public void deleteProject_deletes_webhook_deliveries() {
  1070. ComponentDto project = db.components().insertPublicProject();
  1071. dbClient.webhookDeliveryDao().insert(dbSession, newDto().setComponentUuid(project.uuid()).setUuid("D1").setDurationMs(1000).setWebhookUuid("webhook-uuid"));
  1072. dbClient.webhookDeliveryDao().insert(dbSession, newDto().setComponentUuid("P2").setUuid("D2").setDurationMs(1000).setWebhookUuid("webhook-uuid"));
  1073. underTest.deleteProject(dbSession, project.uuid());
  1074. assertThat(selectAllDeliveryUuids(db, dbSession)).containsOnly("D2");
  1075. }
  1076. @Test
  1077. public void deleteProject_deletes_project_mappings() {
  1078. ComponentDto project = db.components().insertPublicProject();
  1079. dbClient.projectMappingsDao().put(dbSession, "a.key.type", "a.key", project.uuid());
  1080. dbClient.projectMappingsDao().put(dbSession, "a.key.type", "another.key", "D2");
  1081. underTest.deleteProject(dbSession, project.uuid());
  1082. assertThat(dbClient.projectMappingsDao().get(dbSession, "a.key.type", "a.key")).isEmpty();
  1083. assertThat(dbClient.projectMappingsDao().get(dbSession, "a.key.type", "another.key")).isNotEmpty();
  1084. }
  1085. @Test
  1086. public void deleteProject_deletes_project_alm_bindings() {
  1087. ALM alm = ALM.GITHUB;
  1088. String repoId = "123";
  1089. String otherRepoId = repoId + "-foo";
  1090. ComponentDto project = db.components().insertPublicProject();
  1091. ComponentDto otherProject = db.components().insertPublicProject();
  1092. dbClient.projectAlmBindingsDao().insertOrUpdate(dbSession, alm, repoId, project.uuid(), null, "foo");
  1093. dbClient.projectAlmBindingsDao().insertOrUpdate(dbSession, alm, otherRepoId, otherProject.uuid(), null, "bar");
  1094. underTest.deleteProject(dbSession, project.uuid());
  1095. assertThat(dbClient.projectAlmBindingsDao().findProjectKey(dbSession, alm, repoId)).isEmpty();
  1096. assertThat(dbClient.projectAlmBindingsDao().findProjectKey(dbSession, alm, otherRepoId)).isNotEmpty();
  1097. }
  1098. @Test
  1099. public void deleteNonRootComponents_has_no_effect_when_parameter_is_empty() {
  1100. DbSession dbSession = mock(DbSession.class);
  1101. underTest.deleteNonRootComponentsInView(dbSession, Collections.emptyList());
  1102. verifyZeroInteractions(dbSession);
  1103. }
  1104. @Test
  1105. public void deleteNonRootComponents_has_no_effect_when_parameter_contains_only_projects_and_or_views() {
  1106. ComponentDbTester componentDbTester = db.components();
  1107. verifyNoEffect(componentDbTester.insertPrivateProject());
  1108. verifyNoEffect(componentDbTester.insertPublicProject());
  1109. verifyNoEffect(componentDbTester.insertView());
  1110. verifyNoEffect(componentDbTester.insertView(), componentDbTester.insertPrivateProject(), componentDbTester.insertPublicProject());
  1111. }
  1112. @Test
  1113. public void delete_live_measures_when_deleting_project() {
  1114. MetricDto metric = db.measures().insertMetric();
  1115. ComponentDto project1 = db.components().insertPublicProject();
  1116. ComponentDto module1 = db.components().insertComponent(ComponentTesting.newModuleDto(project1));
  1117. db.measures().insertLiveMeasure(project1, metric);
  1118. db.measures().insertLiveMeasure(module1, metric);
  1119. ComponentDto project2 = db.components().insertPublicProject();
  1120. ComponentDto module2 = db.components().insertComponent(ComponentTesting.newModuleDto(project2));
  1121. db.measures().insertLiveMeasure(project2, metric);
  1122. db.measures().insertLiveMeasure(module2, metric);
  1123. underTest.deleteProject(dbSession, project1.uuid());
  1124. assertThat(dbClient.liveMeasureDao().selectByComponentUuidsAndMetricIds(dbSession, asList(project1.uuid(), module1.uuid()), asList(metric.getId()))).isEmpty();
  1125. assertThat(dbClient.liveMeasureDao().selectByComponentUuidsAndMetricIds(dbSession, asList(project2.uuid(), module2.uuid()), asList(metric.getId()))).hasSize(2);
  1126. }
  1127. private void verifyNoEffect(ComponentDto firstRoot, ComponentDto... otherRoots) {
  1128. DbSession dbSession = mock(DbSession.class);
  1129. List<ComponentDto> componentDtos = Stream.concat(Stream.of(firstRoot), Arrays.stream(otherRoots)).collect(Collectors.toList());
  1130. Collections.shuffle(componentDtos); // order of collection must not matter
  1131. underTest.deleteNonRootComponentsInView(dbSession, componentDtos);
  1132. verifyZeroInteractions(dbSession);
  1133. }
  1134. @Test
  1135. public void deleteNonRootComponents_deletes_only_non_root_components_of_a_project_from_table_components() {
  1136. ComponentDto project = new Random().nextBoolean() ? db.components().insertPublicProject() : db.components().insertPrivateProject();
  1137. ComponentDto module1 = db.components().insertComponent(ComponentTesting.newModuleDto(project));
  1138. ComponentDto module2 = db.components().insertComponent(ComponentTesting.newModuleDto(module1));
  1139. ComponentDto dir1 = db.components().insertComponent(newDirectory(module1, "A/B"));
  1140. List<ComponentDto> components = asList(
  1141. project,
  1142. module1,
  1143. module2,
  1144. dir1,
  1145. db.components().insertComponent(newDirectory(module2, "A/C")),
  1146. db.components().insertComponent(newFileDto(dir1)),
  1147. db.components().insertComponent(newFileDto(module2)),
  1148. db.components().insertComponent(newFileDto(project)));
  1149. Collections.shuffle(components);
  1150. underTest.deleteNonRootComponentsInView(dbSession, components);
  1151. assertThat(uuidsIn(" components"))
  1152. .containsOnly(project.uuid());
  1153. }
  1154. @Test
  1155. public void deleteNonRootComponents_deletes_only_non_root_components_of_a_view_from_table_components() {
  1156. ComponentDto[] projects = {
  1157. db.components().insertPrivateProject(),
  1158. db.components().insertPrivateProject(),
  1159. db.components().insertPrivateProject()
  1160. };
  1161. ComponentDto view = db.components().insertView();
  1162. ComponentDto subview1 = db.components().insertComponent(newSubView(view));
  1163. ComponentDto subview2 = db.components().insertComponent(newSubView(subview1));
  1164. List<ComponentDto> components = asList(
  1165. view,
  1166. subview1,
  1167. subview2,
  1168. db.components().insertComponent(newProjectCopy("a", projects[0], view)),
  1169. db.components().insertComponent(newProjectCopy("b", projects[1], subview1)),
  1170. db.components().insertComponent(newProjectCopy("c", projects[2], subview2)));
  1171. Collections.shuffle(components);
  1172. underTest.deleteNonRootComponentsInView(dbSession, components);
  1173. assertThat(uuidsIn(" components"))
  1174. .containsOnly(view.uuid(), projects[0].uuid(), projects[1].uuid(), projects[2].uuid());
  1175. }
  1176. @Test
  1177. public void deleteNonRootComponents_deletes_only_specified_non_root_components_of_a_project_from_table_components() {
  1178. ComponentDto project = new Random().nextBoolean() ? db.components().insertPublicProject() : db.components().insertPrivateProject();
  1179. ComponentDto module1 = db.components().insertComponent(ComponentTesting.newModuleDto(project));
  1180. ComponentDto module2 = db.components().insertComponent(ComponentTesting.newModuleDto(module1));
  1181. ComponentDto dir1 = db.components().insertComponent(newDirectory(module1, "A/B"));
  1182. ComponentDto dir2 = db.components().insertComponent(newDirectory(module2, "A/C"));
  1183. ComponentDto file1 = db.components().insertComponent(newFileDto(dir1));
  1184. ComponentDto file2 = db.components().insertComponent(newFileDto(module2));
  1185. ComponentDto file3 = db.components().insertComponent(newFileDto(project));
  1186. underTest.deleteNonRootComponentsInView(dbSession, singletonList(file3));
  1187. assertThat(uuidsIn("components"))
  1188. .containsOnly(project.uuid(), module1.uuid(), module2.uuid(), dir1.uuid(), dir2.uuid(), file1.uuid(), file2.uuid());
  1189. underTest.deleteNonRootComponentsInView(dbSession, asList(module1, dir2, file1));
  1190. assertThat(uuidsIn("components"))
  1191. .containsOnly(project.uuid(), module2.uuid(), dir1.uuid(), file2.uuid());
  1192. }
  1193. @Test
  1194. public void deleteNonRootComponents_deletes_only_specified_non_root_components_of_a_view_from_table_components() {
  1195. ComponentDto[] projects = {
  1196. db.components().insertPrivateProject(),
  1197. db.components().insertPrivateProject(),
  1198. db.components().insertPrivateProject()
  1199. };
  1200. ComponentDto view = db.components().insertView();
  1201. ComponentDto subview1 = db.components().insertComponent(newSubView(view));
  1202. ComponentDto subview2 = db.components().insertComponent(newSubView(subview1));
  1203. ComponentDto pc1 = db.components().insertComponent(newProjectCopy("a", projects[0], view));
  1204. ComponentDto pc2 = db.components().insertComponent(newProjectCopy("b", projects[1], subview1));
  1205. ComponentDto pc3 = db.components().insertComponent(newProjectCopy("c", projects[2], subview2));
  1206. underTest.deleteNonRootComponentsInView(dbSession, singletonList(pc3));
  1207. assertThat(uuidsIn("components"))
  1208. .containsOnly(view.uuid(), projects[0].uuid(), projects[1].uuid(), projects[2].uuid(),
  1209. subview1.uuid(), subview2.uuid(), pc1.uuid(), pc2.uuid());
  1210. underTest.deleteNonRootComponentsInView(dbSession, asList(subview1, pc2));
  1211. assertThat(uuidsIn("components"))
  1212. .containsOnly(view.uuid(), projects[0].uuid(), projects[1].uuid(), projects[2].uuid(), subview2.uuid(), pc1.uuid());
  1213. assertThat(uuidsIn("projects")).containsOnly(projects[0].uuid(), projects[1].uuid(), projects[2].uuid());
  1214. }
  1215. @Test
  1216. public void deleteNonRootComponents_deletes_measures_of_any_non_root_component_of_a_view() {
  1217. ComponentDto view = db.components().insertView();
  1218. ComponentDto subview = db.components().insertComponent(newSubView(view));
  1219. ComponentDto pc = db.components().insertComponent(newProjectCopy("a", db.components().insertPrivateProject(), view));
  1220. insertMeasureFor(view, subview, pc);
  1221. assertThat(getComponentUuidsOfMeasures()).containsOnly(view.uuid(), subview.uuid(), pc.uuid());
  1222. underTest.deleteNonRootComponentsInView(dbSession, singletonList(pc));
  1223. assertThat(getComponentUuidsOfMeasures())
  1224. .containsOnly(view.uuid(), subview.uuid());
  1225. underTest.deleteNonRootComponentsInView(dbSession, singletonList(subview));
  1226. assertThat(getComponentUuidsOfMeasures())
  1227. .containsOnly(view.uuid());
  1228. }
  1229. @Test
  1230. public void deleteNonRootComponents_deletes_properties_of_subviews_of_a_view() {
  1231. ComponentDto view = db.components().insertView();
  1232. ComponentDto subview1 = db.components().insertComponent(newSubView(view));
  1233. ComponentDto subview2 = db.components().insertComponent(newSubView(subview1));
  1234. ComponentDto subview3 = db.components().insertComponent(newSubView(view));
  1235. ComponentDto pc = db.components().insertComponent(newProjectCopy("a", db.components().insertPrivateProject(), view));
  1236. insertPropertyFor(view, subview1, subview2, subview3, pc);
  1237. assertThat(getResourceIdOfProperties()).containsOnly(view.getId(), subview1.getId(), subview2.getId(), subview3.getId(), pc.getId());
  1238. underTest.deleteNonRootComponentsInView(dbSession, singletonList(subview1));
  1239. assertThat(getResourceIdOfProperties())
  1240. .containsOnly(view.getId(), subview2.getId(), subview3.getId(), pc.getId());
  1241. underTest.deleteNonRootComponentsInView(dbSession, asList(subview2, subview3, pc));
  1242. assertThat(getResourceIdOfProperties())
  1243. .containsOnly(view.getId(), pc.getId());
  1244. }
  1245. @Test
  1246. public void deleteNonRootComponentsInView_deletes_manual_measures_of_subviews_of_a_view() {
  1247. ComponentDto view = db.components().insertView();
  1248. ComponentDto subview1 = db.components().insertComponent(newSubView(view));
  1249. ComponentDto subview2 = db.components().insertComponent(newSubView(subview1));
  1250. ComponentDto subview3 = db.components().insertComponent(newSubView(view));
  1251. ComponentDto pc = db.components().insertComponent(newProjectCopy("a", db.components().insertPrivateProject(), view));
  1252. insertManualMeasureFor(view, subview1, subview2, subview3, pc);
  1253. assertThat(getComponentUuidsOfManualMeasures()).containsOnly(view.uuid(), subview1.uuid(), subview2.uuid(), subview3.uuid(), pc.uuid());
  1254. underTest.deleteNonRootComponentsInView(dbSession, singletonList(subview1));
  1255. assertThat(getComponentUuidsOfManualMeasures())
  1256. .containsOnly(view.uuid(), subview2.uuid(), subview3.uuid(), pc.uuid());
  1257. underTest.deleteNonRootComponentsInView(dbSession, asList(subview2, subview3, pc));
  1258. assertThat(getComponentUuidsOfManualMeasures())
  1259. .containsOnly(view.uuid(), pc.uuid());
  1260. }
  1261. @Test
  1262. public void purgeCeActivities_deletes_activity_older_than_180_days_and_their_scanner_context() {
  1263. LocalDateTime now = LocalDateTime.now();
  1264. insertCeActivityAndChildDataWithDate("VERY_OLD", now.minusDays(180).minusMonths(10));
  1265. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH", now.minusDays(180).minusDays(1));
  1266. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH", now.minusDays(180));
  1267. insertCeActivityAndChildDataWithDate("RECENT", now.minusDays(1));
  1268. when(system2.now()).thenReturn(now.toInstant(ZoneOffset.UTC).toEpochMilli());
  1269. underTest.purgeCeActivities(db.getSession(), new PurgeProfiler());
  1270. assertThat(selectActivity("VERY_OLD")).isEmpty();
  1271. assertThat(selectTaskInput("VERY_OLD")).isEmpty();
  1272. assertThat(selectTaskCharacteristic("VERY_OLD")).hasSize(0);
  1273. assertThat(scannerContextExists("VERY_OLD")).isFalse();
  1274. assertThat(selectActivity("JUST_OLD_ENOUGH")).isEmpty();
  1275. assertThat(selectTaskInput("JUST_OLD_ENOUGH")).isEmpty();
  1276. assertThat(selectTaskCharacteristic("JUST_OLD_ENOUGH")).hasSize(0);
  1277. assertThat(scannerContextExists("JUST_OLD_ENOUGH")).isFalse();
  1278. assertThat(selectActivity("NOT_OLD_ENOUGH")).isNotEmpty();
  1279. assertThat(selectTaskInput("NOT_OLD_ENOUGH")).isNotEmpty();
  1280. assertThat(selectTaskCharacteristic("NOT_OLD_ENOUGH")).hasSize(1);
  1281. assertThat(scannerContextExists("NOT_OLD_ENOUGH")).isTrue();
  1282. assertThat(selectActivity("RECENT")).isNotEmpty();
  1283. assertThat(selectTaskInput("RECENT")).isNotEmpty();
  1284. assertThat(selectTaskCharacteristic("RECENT")).hasSize(1);
  1285. assertThat(scannerContextExists("RECENT")).isTrue();
  1286. }
  1287. @Test
  1288. public void purgeCeScannerContexts_deletes_ce_scanner_context_older_than_28_days() {
  1289. LocalDateTime now = LocalDateTime.now();
  1290. insertCeActivityAndChildDataWithDate("VERY_OLD", now.minusDays(28).minusMonths(12));
  1291. insertCeActivityAndChildDataWithDate("JUST_OLD_ENOUGH", now.minusDays(28).minusDays(1));
  1292. insertCeActivityAndChildDataWithDate("NOT_OLD_ENOUGH", now.minusDays(28));
  1293. insertCeActivityAndChildDataWithDate("RECENT", now.minusDays(1));
  1294. when(system2.now()).thenReturn(now.toInstant(ZoneOffset.UTC).toEpochMilli());
  1295. underTest.purgeCeScannerContexts(db.getSession(), new PurgeProfiler());
  1296. assertThat(scannerContextExists("VERY_OLD")).isFalse();
  1297. assertThat(scannerContextExists("JUST_OLD_ENOUGH")).isFalse();
  1298. assertThat(scannerContextExists("NOT_OLD_ENOUGH")).isTrue();
  1299. assertThat(scannerContextExists("RECENT")).isTrue();
  1300. }
  1301. private Optional<CeActivityDto> selectActivity(String taskUuid) {
  1302. return db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), taskUuid);
  1303. }
  1304. private List<CeTaskCharacteristicDto> selectTaskCharacteristic(String taskUuid) {
  1305. return db.getDbClient().ceTaskCharacteristicsDao().selectByTaskUuids(db.getSession(), Collections.singletonList(taskUuid));
  1306. }
  1307. private Optional<CeTaskInputDao.DataStream> selectTaskInput(String taskUuid) {
  1308. return db.getDbClient().ceTaskInputDao().selectData(db.getSession(), taskUuid);
  1309. }
  1310. private boolean scannerContextExists(String uuid) {
  1311. return db.countSql("select count(1) from ce_scanner_context where task_uuid = '" + uuid + "'") == 1;
  1312. }
  1313. @SafeVarargs
  1314. private final void insertCeActivityAndChildDataWithDate(String ceActivityUuid, LocalDateTime dateTime,
  1315. Consumer<CeQueueDto>... queueDtoConsumers) {
  1316. long date = dateTime.toInstant(UTC).toEpochMilli();
  1317. CeQueueDto queueDto = new CeQueueDto();
  1318. queueDto.setUuid(ceActivityUuid);
  1319. queueDto.setTaskType(CeTaskTypes.REPORT);
  1320. Arrays.stream(queueDtoConsumers).forEach(t -> t.accept(queueDto));
  1321. CeActivityDto dto = new CeActivityDto(queueDto);
  1322. dto.setStatus(CeActivityDto.Status.SUCCESS);
  1323. when(system2.now()).thenReturn(date);
  1324. insertCeTaskInput(dto.getUuid());
  1325. insertCeTaskCharacteristics(dto.getUuid(), 1);
  1326. insertCeScannerContext(dto.getUuid());
  1327. insertCeTaskMessages(dto.getUuid(), 2);
  1328. db.getDbClient().ceActivityDao().insert(db.getSession(), dto);
  1329. db.getSession().commit();
  1330. }
  1331. private void insertManualMeasureFor(ComponentDto... componentDtos) {
  1332. Arrays.stream(componentDtos).forEach(componentDto -> dbClient.customMeasureDao().insert(dbSession, new CustomMeasureDto()
  1333. .setComponentUuid(componentDto.uuid())
  1334. .setMetricId(new Random().nextInt())));
  1335. dbSession.commit();
  1336. }
  1337. private Stream<String> getComponentUuidsOfManualMeasures() {
  1338. return db.select("select component_uuid as \"COMPONENT_UUID\" from manual_measures").stream()
  1339. .map(row -> (String) row.get("COMPONENT_UUID"));
  1340. }
  1341. private Stream<Long> getResourceIdOfProperties() {
  1342. return db.select("select resource_id as \"ID\" from properties").stream()
  1343. .map(row -> (Long) row.get("ID"));
  1344. }
  1345. private void insertPropertyFor(ComponentDto... components) {
  1346. Stream.of(components).forEach(componentDto -> db.properties().insertProperty(new PropertyDto()
  1347. .setKey(randomAlphabetic(3))
  1348. .setValue(randomAlphabetic(3))
  1349. .setResourceId(componentDto.getId())));
  1350. }
  1351. private Stream<String> getComponentUuidsOfMeasures() {
  1352. return db.select("select component_uuid as \"COMPONENT_UUID\" from project_measures").stream()
  1353. .map(row -> (String) row.get("COMPONENT_UUID"));
  1354. }
  1355. private void insertMeasureFor(ComponentDto... components) {
  1356. Arrays.stream(components).forEach(componentDto -> db.getDbClient().measureDao().insert(dbSession, new MeasureDto()
  1357. .setMetricId(new Random().nextInt())
  1358. .setComponentUuid(componentDto.uuid())
  1359. .setAnalysisUuid(randomAlphabetic(3))));
  1360. dbSession.commit();
  1361. }
  1362. private CeQueueDto createCeQueue(ComponentDto component, Status status) {
  1363. CeQueueDto queueDto = new CeQueueDto();
  1364. queueDto.setUuid(Uuids.create());
  1365. queueDto.setTaskType(REPORT);
  1366. queueDto.setComponentUuid(component.uuid());
  1367. queueDto.setMainComponentUuid(firstNonNull(component.getMainBranchProjectUuid(), component.uuid()));
  1368. queueDto.setSubmitterUuid("submitter uuid");
  1369. queueDto.setCreatedAt(1_300_000_000_000L);
  1370. queueDto.setStatus(status);
  1371. return queueDto;
  1372. }
  1373. private CeActivityDto insertCeActivity(ComponentDto component) {
  1374. Status unusedStatus = Status.values()[RandomUtils.nextInt(Status.values().length)];
  1375. CeQueueDto queueDto = createCeQueue(component, unusedStatus);
  1376. CeActivityDto dto = new CeActivityDto(queueDto);
  1377. dto.setStatus(CeActivityDto.Status.SUCCESS);
  1378. dto.setStartedAt(1_500_000_000_000L);
  1379. dto.setExecutedAt(1_500_000_000_500L);
  1380. dto.setExecutionTimeMs(500L);
  1381. dbClient.ceActivityDao().insert(dbSession, dto);
  1382. return dto;
  1383. }
  1384. private CeQueueDto insertCeQueue(ComponentDto component) {
  1385. CeQueueDto res = new CeQueueDto()
  1386. .setUuid(UuidFactoryFast.getInstance().create())
  1387. .setTaskType("foo")
  1388. .setComponentUuid(component.uuid())
  1389. .setMainComponentUuid(firstNonNull(component.getMainBranchProjectUuid(), component.uuid()))
  1390. .setStatus(Status.PENDING)
  1391. .setCreatedAt(1_2323_222L)
  1392. .setUpdatedAt(1_2323_222L);
  1393. dbClient.ceQueueDao().insert(dbSession, res);
  1394. dbSession.commit();
  1395. return res;
  1396. }
  1397. private void insertCeScannerContext(String uuid) {
  1398. dbClient.ceScannerContextDao().insert(dbSession, uuid, CloseableIterator.from(Arrays.asList("a", "b", "c").iterator()));
  1399. dbSession.commit();
  1400. }
  1401. private void insertCeTaskCharacteristics(String uuid, int count) {
  1402. List<CeTaskCharacteristicDto> dtos = IntStream.range(0, count)
  1403. .mapToObj(i -> new CeTaskCharacteristicDto()
  1404. .setUuid(UuidFactoryFast.getInstance().create())
  1405. .setTaskUuid(uuid)
  1406. .setKey("key_" + uuid.hashCode() + i)
  1407. .setValue("value_" + uuid.hashCode() + i))
  1408. .collect(Collectors.toList());
  1409. dbClient.ceTaskCharacteristicsDao().insert(dbSession, dtos);
  1410. dbSession.commit();
  1411. }
  1412. private void insertCeTaskInput(String uuid) {
  1413. dbClient.ceTaskInputDao().insert(dbSession, uuid, new ByteArrayInputStream("some content man!".getBytes()));
  1414. dbSession.commit();
  1415. }
  1416. private void insertCeTaskMessages(String uuid, int count) {
  1417. IntStream.range(0, count)
  1418. .mapToObj(i -> new CeTaskMessageDto()
  1419. .setUuid(UuidFactoryFast.getInstance().create())
  1420. .setTaskUuid(uuid)
  1421. .setMessage("key_" + uuid.hashCode() + i)
  1422. .setCreatedAt(2_333_444L + i))
  1423. .forEach(dto -> dbClient.ceTaskMessageDao().insert(dbSession, dto));
  1424. dbSession.commit();
  1425. }
  1426. private static PurgeableAnalysisDto getById(List<PurgeableAnalysisDto> snapshots, String uuid) {
  1427. return snapshots.stream()
  1428. .filter(snapshot -> uuid.equals(snapshot.getAnalysisUuid()))
  1429. .findFirst()
  1430. .orElse(null);
  1431. }
  1432. private Stream<String> uuidsIn(String tableName) {
  1433. return uuidsIn(tableName, "uuid");
  1434. }
  1435. private Stream<String> taskUuidsIn(String tableName) {
  1436. return uuidsIn(tableName, "task_uuid");
  1437. }
  1438. private Stream<String> uuidsIn(String tableName, String columnName) {
  1439. return db.select("select " + columnName + " as \"UUID\" from " + tableName)
  1440. .stream()
  1441. .map(row -> (String) row.get("UUID"));
  1442. }
  1443. private static PurgeConfiguration newConfigurationWith30Days(String rootUuid) {
  1444. return new PurgeConfiguration(rootUuid, rootUuid, 30, Optional.of(30), System2.INSTANCE, emptySet());
  1445. }
  1446. private static PurgeConfiguration newConfigurationWith30Days(System2 system2, String rootUuid, String projectUuid) {
  1447. return newConfigurationWith30Days(system2, rootUuid, projectUuid, Collections.emptySet());
  1448. }
  1449. private static PurgeConfiguration newConfigurationWith30Days(System2 system2, String rootUuid, String projectUuid, Set<String> disabledComponentUuids) {
  1450. return new PurgeConfiguration(rootUuid, projectUuid, 30, Optional.of(30), system2, disabledComponentUuids);
  1451. }
  1452. private Stream<String> uuidsOfAnalysesOfRoot(ComponentDto rootComponent) {
  1453. return db.select("select uuid as \"UUID\" from snapshots where component_uuid='" + rootComponent.uuid() + "'")
  1454. .stream()
  1455. .map(t -> (String) t.get("UUID"));
  1456. }
  1457. private static IdUuidPair idUuidPairOf(SnapshotDto analysis3) {
  1458. return new IdUuidPair(analysis3.getId(), analysis3.getUuid());
  1459. }
  1460. }