]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-15139 - Purge Branch properties
authorBelen Pruvost <belen.pruvost@sonarsource.com>
Wed, 28 Jul 2021 17:42:58 +0000 (19:42 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 9 Aug 2021 20:03:17 +0000 (20:03 +0000)
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java
server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java

index a4f366c7c981b328bce9b5f474a67fa45bbc32ba..8eec8a70106e7e3181af37df9ad5eeb0d7c6294b 100644 (file)
@@ -248,6 +248,13 @@ class PurgeCommands {
     profiler.stop();
   }
 
+  void deleteOutdatedProperties(String branchUuid) {
+    profiler.start("deleteOutdatedProperties (properties)");
+    purgeMapper.deletePropertiesByComponentUuids(List.of(branchUuid));
+    session.commit();
+    profiler.stop();
+  }
+
   void deleteComponents(String rootUuid) {
     profiler.start("deleteComponents (projects)");
     purgeMapper.deleteComponentsByProjectUuid(rootUuid);
index ac746986d51e73718f0bc9b0156a3dea956e669a..6a02b221547b481f06a641b849870fd7cfcda08f 100644 (file)
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Predicate;
+import java.util.stream.Collectors;
 import javax.annotation.Nullable;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.System2;
@@ -37,6 +38,7 @@ import org.sonar.db.Dao;
 import org.sonar.db.DbSession;
 import org.sonar.db.audit.AuditPersister;
 import org.sonar.db.audit.model.ComponentNewValue;
+import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.BranchMapper;
 import org.sonar.db.component.ComponentDto;
 
@@ -54,7 +56,7 @@ public class PurgeDao implements Dao {
   private final System2 system2;
   private AuditPersister auditPersister;
 
-  public PurgeDao(System2 system2) {
+  public PurgeDao(System2 system2)  {
     this.system2 = system2;
   }
 
@@ -192,9 +194,13 @@ public class PurgeDao implements Dao {
     PurgeCommands purgeCommands = new PurgeCommands(session, profiler, system2);
     long start = System2.INSTANCE.now();
 
-    session.getMapper(BranchMapper.class).selectByProjectUuid(uuid).stream()
+    List<String> branchUuids = session.getMapper(BranchMapper.class).selectByProjectUuid(uuid).stream()
       .filter(branch -> !uuid.equals(branch.getUuid()))
-      .forEach(branch -> deleteRootComponent(branch.getUuid(), purgeMapper, purgeCommands));
+      .map(BranchDto::getUuid)
+      .collect(Collectors.toList());
+
+    branchUuids.stream()
+      .forEach(id -> deleteRootComponent(id, purgeMapper, purgeCommands));
 
     deleteRootComponent(uuid, purgeMapper, purgeCommands);
 
@@ -239,6 +245,7 @@ public class PurgeDao implements Dao {
     commands.deleteComponentsByMainBranchProjectUuid(rootUuid);
     commands.deleteProject(rootUuid);
     commands.deleteUserDismissedMessages(rootUuid);
+    commands.deleteOutdatedProperties(rootUuid);
   }
 
   /**
index 2ae4fc8bf4c626bcaaaeaf8c82f7c95c2f90a7f4..e90f267625ff22b8b6c7ad9d8bd4ef0adb9bf9ab 100644 (file)
@@ -469,6 +469,23 @@ public class PurgeCommandsTest {
     assertThat(countAnalysisPropertiesOf(otherAnalysis)).isEqualTo(count);
   }
 
+  @Test
+  @UseDataProvider("projects")
+  public void deleteOutdatedProperties_deletes_properties_by_component_uuid(ComponentDto project) {
+    ComponentDto component = dbTester.components().insertComponent(project);
+    ComponentDto anotherComponent = dbTester.components().insertPublicProject();
+    int count = 4;
+    IntStream.range(0, count).forEach(i -> {
+      insertRandomProperty(component);
+      insertRandomProperty(anotherComponent);
+    });
+
+    underTest.deleteOutdatedProperties(component.uuid());
+
+    assertThat(countPropertiesOf(component)).isZero();
+    assertThat(countPropertiesOf(anotherComponent)).isEqualTo(count);
+  }
+
   @Test
   @UseDataProvider("projectsAndViews")
   public void deleteIssues_deletes_all_issues_of_specified_root_component(ComponentDto projectOrView) {
@@ -706,6 +723,10 @@ public class PurgeCommandsTest {
     return dbTester.countSql("select count(1) from analysis_properties where analysis_uuid='" + analysis.getUuid() + "'");
   }
 
+  private int countPropertiesOf(ComponentDto componentDto) {
+    return dbTester.countSql("select count(1) from properties where component_uuid='" + componentDto.uuid() + "'");
+  }
+
   private int countEventsOf(SnapshotDto analysis) {
     return dbTester.countSql("select count(1) from events where analysis_uuid='" + analysis.getUuid() + "'");
   }
@@ -730,6 +751,18 @@ public class PurgeCommandsTest {
       "CREATED_AT", 1L);
   }
 
+  private void insertRandomProperty(ComponentDto component) {
+    boolean isEmpty = new Random().nextBoolean();
+    dbTester.executeInsert(
+      "PROPERTIES",
+      "UUID", newUuid(),
+      "PROP_KEY", randomAlphabetic(10),
+      "COMPONENT_UUID", component.uuid(),
+      "TEXT_VALUE", randomAlphabetic(10),
+      "IS_EMPTY", isEmpty,
+      "CREATED_AT", 1L);
+  }
+
   private int countAnalysesOfRoot(ComponentDto projectOrView) {
     return dbTester.countSql("select count(1) from snapshots where component_uuid='" + projectOrView.uuid() + "'");
   }
index 375d425eecf1120e0e4a1b8598e4f90df2942a53..e99f56902fb2880a57633b8c5006fe6201f339f4 100644 (file)
@@ -24,6 +24,7 @@ import java.io.ByteArrayInputStream;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
@@ -217,12 +218,18 @@ public class PurgeDaoTest {
     ComponentDto branch1 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
     db.components().insertSnapshot(branch1, dto -> dto.setCreatedAt(DateUtils.addDays(new Date(), -31).getTime()));
 
-    // branch with other components and issues, updated 31 days ago
+    // branches with other components and issues, updated 31 days ago
     ComponentDto branch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST));
     db.components().insertSnapshot(branch2, dto -> dto.setCreatedAt(DateUtils.addDays(new Date(), -31).getTime()));
     ComponentDto file = db.components().insertComponent(newFileDto(branch2));
     db.issues().insert(rule, branch2, file);
 
+    ComponentDto branch3 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
+    db.components().insertSnapshot(branch3, dto -> dto.setCreatedAt(DateUtils.addDays(new Date(), -31).getTime()));
+
+    // properties exist or active and for inactive branch
+    insertPropertyFor(branch3, branch1);
+
     // analysing branch1
     underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, branch1.uuid(), branch1.getMainBranchProjectUuid()), PurgeListener.EMPTY, new PurgeProfiler());
     dbSession.commit();
@@ -230,6 +237,7 @@ public class PurgeDaoTest {
     // branch1 wasn't deleted since it was being analyzed!
     assertThat(uuidsIn("components")).containsOnly(project.uuid(), nonMainBranch.uuid(), branch1.uuid());
     assertThat(uuidsIn("projects")).containsOnly(project.uuid());
+    assertThat(componentUuidsIn("properties")).containsOnly(branch1.uuid());
   }
 
   @Test
@@ -623,6 +631,9 @@ public class PurgeDaoTest {
     db.components().addProjectBranchToApplicationBranch(dbClient.branchDao().selectByUuid(dbSession, appBranch.uuid()).get(), projectBranch);
     db.components().addProjectBranchToApplicationBranch(dbClient.branchDao().selectByUuid(dbSession, otherAppBranch.uuid()).get(), projectBranch);
 
+    // properties exist or active and for inactive branch
+    insertPropertyFor(appBranch, otherAppBranch);
+
     underTest.deleteBranch(dbSession, appBranch.uuid());
     dbSession.commit();
 
@@ -633,6 +644,8 @@ public class PurgeDaoTest {
     assertThat(uuidsIn("project_measures")).containsOnly(appMeasure.getUuid(), otherAppMeasure.getUuid(), otherAppBranchMeasure.getUuid());
     assertThat(uuidsIn("app_projects", "application_uuid")).containsOnly(app.uuid(), otherApp.uuid());
     assertThat(uuidsIn("app_branch_project_branch", "application_branch_uuid")).containsOnly(otherAppBranch.uuid());
+    assertThat(componentUuidsIn("properties")).containsOnly(otherAppBranch.uuid());
+
   }
 
   @Test
@@ -1053,8 +1066,18 @@ public class PurgeDaoTest {
     int projectEntryCount = db.countRowsOfTable("components");
     int issueCount = db.countRowsOfTable("issues");
     int branchCount = db.countRowsOfTable("project_branches");
+    Collection<BranchDto> anotherLivingProjectBranches = db.getDbClient().branchDao()
+      .selectByComponent(db.getSession(), anotherLivingProject);
+    insertPropertyFor(anotherLivingProjectBranches);
+
+    assertThat(db.countRowsOfTable("properties")).isEqualTo(anotherLivingProjectBranches.size());
 
     ComponentDto projectToDelete = insertProjectWithBranchAndRelatedData();
+    Collection<BranchDto> projectToDeleteBranches = db.getDbClient().branchDao()
+      .selectByComponent(db.getSession(), projectToDelete);
+    insertPropertyFor(projectToDeleteBranches);
+
+    assertThat(db.countRowsOfTable("properties")).isEqualTo(anotherLivingProjectBranches.size() + projectToDeleteBranches.size());
     assertThat(db.countRowsOfTable("components")).isGreaterThan(projectEntryCount);
     assertThat(db.countRowsOfTable("issues")).isGreaterThan(issueCount);
     assertThat(db.countRowsOfTable("project_branches")).isGreaterThan(branchCount);
@@ -1065,6 +1088,7 @@ public class PurgeDaoTest {
     assertThat(db.countRowsOfTable("components")).isEqualTo(projectEntryCount);
     assertThat(db.countRowsOfTable("issues")).isEqualTo(issueCount);
     assertThat(db.countRowsOfTable("project_branches")).isEqualTo(branchCount);
+    assertThat(db.countRowsOfTable("properties")).isEqualTo(anotherLivingProjectBranches.size());
   }
 
   @Test
@@ -1639,6 +1663,14 @@ public class PurgeDaoTest {
       componentDto.name(), null));
   }
 
+  private void insertPropertyFor(Collection<BranchDto> branches) {
+    branches.stream().forEach(branchDto -> db.properties().insertProperty(new PropertyDto()
+        .setKey(randomAlphabetic(3))
+        .setValue(randomAlphabetic(3))
+        .setComponentUuid(branchDto.getUuid()),
+      branchDto.getKey(), null));
+  }
+
   private Stream<String> getComponentUuidsOfMeasures() {
     return db.select("select component_uuid as \"COMPONENT_UUID\" from project_measures").stream()
       .map(row -> (String) row.get("COMPONENT_UUID"));
@@ -1736,6 +1768,10 @@ public class PurgeDaoTest {
     return uuidsIn(tableName, "uuid");
   }
 
+  private Stream<String> componentUuidsIn(String tableName) {
+    return uuidsIn(tableName, "component_uuid");
+  }
+
   private Stream<String> taskUuidsIn(String tableName) {
     return uuidsIn(tableName, "task_uuid");
   }