]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20481 fixed the issue where removing a branch was removing a project too
authorlukasz-jarocki-sonarsource <lukasz.jarocki@sonarsource.com>
Tue, 19 Sep 2023 14:42:51 +0000 (16:42 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 20 Sep 2023 20:02:50 +0000 (20:02 +0000)
server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeCommandsIT.java
server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java
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/main/java/org/sonar/db/purge/PurgeMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml

index 890a6f81ee78f6aa9ee5950b37e1f9dc312d485f..6df2ca7cd22ebce90a7aeb44149ede4807232944 100644 (file)
@@ -263,7 +263,7 @@ public class PurgeCommandsIT {
 
   @Test
   @UseDataProvider("projectsAndViews")
-  public void deleteAnalyses_by_rootUuid_deletes_event_component_changes(ComponentDto projectOrView) {
+  public void deleteEventComponentChanges_shouldDeleteEventComponentChanges(ComponentDto projectOrView) {
     dbTester.components().insertComponent(projectOrView);
     ComponentDto otherProject = dbTester.components().insertPrivateProject().getMainBranchComponent();
     int count = 5;
@@ -272,7 +272,7 @@ public class PurgeCommandsIT {
       insertRandomEventComponentChange(otherProject);
     });
 
-    underTest.deleteAnalyses(projectOrView.uuid());
+    underTest.deleteEventComponentChanges(projectOrView.uuid());
 
     assertThat(countEventComponentChangesOf(projectOrView)).isZero();
     assertThat(countEventComponentChangesOf(otherProject)).isEqualTo(count);
@@ -646,7 +646,7 @@ public class PurgeCommandsIT {
     dbTester.newCodePeriods().insert(project.uuid(), branch.getUuid(), NewCodePeriodType.NUMBER_OF_DAYS, "1");
 
     PurgeCommands purgeCommands = new PurgeCommands(dbTester.getSession(), profiler, system2);
-    purgeCommands.deleteNewCodePeriods(branch.getUuid());
+    purgeCommands.deleteNewCodePeriodsForBranch(branch.getUuid());
 
     // should delete branch settings only
     assertThat(dbTester.countRowsOfTable("new_code_periods")).isEqualTo(2);
@@ -668,7 +668,7 @@ public class PurgeCommandsIT {
     dbTester.newCodePeriods().insert(project.uuid(), branch.getUuid(), NewCodePeriodType.NUMBER_OF_DAYS, "1");
 
     PurgeCommands purgeCommands = new PurgeCommands(dbTester.getSession(), profiler, system2);
-    purgeCommands.deleteNewCodePeriods(project.uuid());
+    purgeCommands.deleteNewCodePeriodsForProject(project.uuid());
 
     // should delete branch and project settings only
     assertThat(dbTester.countRowsOfTable("new_code_periods")).isOne();
@@ -690,7 +690,7 @@ public class PurgeCommandsIT {
     dbTester.newCodePeriods().insert(project.uuid(), branch.getUuid(), NewCodePeriodType.NUMBER_OF_DAYS, "1");
 
     PurgeCommands purgeCommands = new PurgeCommands(dbTester.getSession(), profiler, system2);
-    purgeCommands.deleteNewCodePeriods(null);
+    purgeCommands.deleteNewCodePeriodsForProject(null);
 
     // should delete branch and project settings only
     assertThat(dbTester.countRowsOfTable("new_code_periods")).isEqualTo(3);
index 808bb724f1259e3b777c41e8096caa90f735bdab..42b6cae190534f6bb03a295e80447424441d2ed5 100644 (file)
@@ -266,11 +266,6 @@ public class PurgeDaoIT {
     BranchDto branch3 = db.components().insertProjectBranch(project.getProjectDto(), 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
-    ComponentDto branch1Component = db.components().getComponentDto(branch1);
-    ComponentDto branch3Component = db.components().getComponentDto(branch3);
-    insertPropertyFor(branch3Component, branch1Component);
-
     // analysing branch1
     underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, branch1.getUuid(), project.getProjectDto().getUuid()), PurgeListener.EMPTY, new PurgeProfiler());
     dbSession.commit();
@@ -278,7 +273,6 @@ public class PurgeDaoIT {
     // branch1 wasn't deleted since it was being analyzed!
     assertThat(uuidsIn("components")).containsOnly(project.getMainBranchDto().getUuid(), nonMainBranch.getUuid(), branch1.getUuid());
     assertThat(uuidsIn("projects")).containsOnly(project.getProjectDto().getUuid());
-    assertThat(componentUuidsIn("properties")).containsOnly(branch1.getUuid());
   }
 
   @Test
@@ -592,7 +586,7 @@ public class PurgeDaoIT {
     ProjectData project = db.components().insertPrivateProject();
     ComponentDto directory = db.components().insertComponent(newDirectory(project.getMainBranchComponent(), "a/b"));
     ComponentDto file = db.components().insertComponent(newFileDto(directory));
-    SnapshotDto analysis = db.components().insertSnapshot(project.getProjectDto());
+    SnapshotDto analysis = db.components().insertSnapshot(project.getMainBranchDto());
     IssueDto issue1 = db.issues().insert(rule, project.getMainBranchComponent(), file);
     IssueChangeDto issueChange1 = db.issues().insertChange(issue1);
     IssueDto issue2 = db.issues().insert(rule, project.getMainBranchComponent(), file);
@@ -602,7 +596,7 @@ public class PurgeDaoIT {
     ProjectData otherProject = db.components().insertPrivateProject();
     ComponentDto otherDirectory = db.components().insertComponent(newDirectory(otherProject.getMainBranchComponent(), "a/b"));
     ComponentDto otherFile = db.components().insertComponent(newFileDto(otherDirectory));
-    SnapshotDto otherAnalysis = db.components().insertSnapshot(otherProject.getProjectDto());
+    SnapshotDto otherAnalysis = db.components().insertSnapshot(otherProject.getMainBranchDto());
     IssueDto otherIssue1 = db.issues().insert(rule, otherProject.getMainBranchComponent(), otherFile);
     IssueChangeDto otherIssueChange1 = db.issues().insertChange(otherIssue1);
     IssueDto otherIssue2 = db.issues().insert(rule, otherProject.getMainBranchComponent(), otherFile);
@@ -693,8 +687,9 @@ public class PurgeDaoIT {
     db.components().addProjectBranchToApplicationBranch(dbClient.branchDao().selectByUuid(dbSession, appBranch.getUuid()).get(), projectBranch);
     db.components().addProjectBranchToApplicationBranch(dbClient.branchDao().selectByUuid(dbSession, otherAppBranch.getUuid()).get(), projectBranch);
 
-    // properties exist or active and for inactive branch
-    insertPropertyFor(appBranchComponent, otherAppBranchComponent);
+    // properties exist only for entities, not branches
+    insertPropertyFor(app.getProjectDto());
+    insertPropertyFor(otherApp.getProjectDto());
 
     insertReportScheduleAndSubscriptionForBranch(appBranch.getUuid(), dbSession);
 
@@ -710,7 +705,8 @@ public class PurgeDaoIT {
     assertThat(uuidsIn("project_measures")).containsOnly(appMeasure.getUuid(), otherAppMeasure.getUuid(), otherAppBranchMeasure.getUuid());
     assertThat(uuidsIn("app_projects", "application_uuid")).containsOnly(app.getProjectDto().getUuid(), otherApp.getProjectDto().getUuid());
     assertThat(uuidsIn("app_branch_project_branch", "application_branch_uuid")).containsOnly(otherAppBranch.getUuid());
-    assertThat(componentUuidsIn("properties")).containsOnly(otherAppBranch.getUuid());
+    //properties should not change as we are deleting a branch, not application
+    assertThat(componentUuidsIn("properties")).containsOnly(otherApp.projectUuid(), app.projectUuid());
     assertThat(uuidsIn("report_schedules", "branch_uuid")).isEmpty();
     assertThat(uuidsIn("report_subscriptions", "branch_uuid")).isEmpty();
 
@@ -1165,18 +1161,14 @@ public class PurgeDaoIT {
     int projectEntryCount = db.countRowsOfTable("components");
     int issueCount = db.countRowsOfTable("issues");
     int branchCount = db.countRowsOfTable("project_branches");
-    Collection<BranchDto> anotherLivingProjectBranches = db.getDbClient().branchDao()
-      .selectByProject(db.getSession(), anotherLivingProject);
-    insertPropertyFor(anotherLivingProjectBranches);
+    insertPropertyFor(anotherLivingProject);
 
-    assertThat(db.countRowsOfTable("properties")).isEqualTo(anotherLivingProjectBranches.size());
+    assertThat(db.countRowsOfTable("properties")).isEqualTo(1);
 
     ProjectDto projectToDelete = insertProjectWithBranchAndRelatedData();
-    Collection<BranchDto> projectToDeleteBranches = db.getDbClient().branchDao()
-      .selectByProject(db.getSession(), projectToDelete);
-    insertPropertyFor(projectToDeleteBranches);
+    insertPropertyFor(projectToDelete);
 
-    assertThat(db.countRowsOfTable("properties")).isEqualTo(anotherLivingProjectBranches.size() + projectToDeleteBranches.size());
+    assertThat(db.countRowsOfTable("properties")).isEqualTo(2);
     assertThat(db.countRowsOfTable("components")).isGreaterThan(projectEntryCount);
     assertThat(db.countRowsOfTable("issues")).isGreaterThan(issueCount);
     assertThat(db.countRowsOfTable("project_branches")).isGreaterThan(branchCount);
@@ -1187,7 +1179,7 @@ public class PurgeDaoIT {
     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());
+    assertThat(db.countRowsOfTable("properties")).isEqualTo(1);
   }
 
   @Test
@@ -1856,6 +1848,22 @@ public class PurgeDaoIT {
     assertThat(anticipatedTransitionDtos).hasSize(1);
     assertThat(anticipatedTransitionDtos.get(0).getUuid()).isEqualTo("okTransition");
   }
+  
+  @Test
+  public void deleteBranch_shouldNotRemoveOldProjectWithSameUuidAsBranch() {
+    ComponentDto componentDto = ComponentTesting.newPrivateProjectDto().setUuid("uuid");
+    ProjectData projectData = db.components().insertPrivateProject("uuid", componentDto);
+    BranchDto branch = db.components().insertProjectBranch(projectData.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH));
+
+    insertPropertyFor(projectData.getProjectDto());
+
+    underTest.deleteBranch(dbSession, "uuid");
+
+    assertThat(componentUuidsIn("properties")).containsOnly("uuid");
+    assertThat(uuidsIn("project_branches")).containsOnly(branch.getUuid());
+    assertThat(uuidsIn("projects")).containsOnly("uuid");
+
+  }
 
   private AnticipatedTransitionDto getAnticipatedTransitionsDto(String uuid, String projectUuid, Date creationDate) {
     return new AnticipatedTransitionDto(uuid, projectUuid, "userUuid", "transition", null, null, null, null, "rule:key", "filepath", creationDate.getTime());
@@ -1910,12 +1918,12 @@ public class PurgeDaoIT {
       componentDto.getKey(), componentDto.name(), componentDto.qualifier(), null));
   }
 
-  private void insertPropertyFor(Collection<BranchDto> branches) {
-    branches.stream().forEach(branchDto -> db.properties().insertProperty(new PropertyDto()
+  private void insertPropertyFor(ProjectDto project) {
+    db.properties().insertProperty(new PropertyDto()
       .setKey(randomAlphabetic(3))
       .setValue(randomAlphabetic(3))
-      .setEntityUuid(branchDto.getUuid()),
-      null, branchDto.getKey(), null, null));
+      .setEntityUuid(project.getUuid()),
+      null, project.getKey(), null, null);
   }
 
   private Stream<String> getComponentUuidsOfMeasures() {
index 0c086d15e0863edf22dc73b243e0fad11c9e8e62..05f2efb1bf71e9d41a9855ebf3778e2ebcf6a6b2 100644 (file)
@@ -55,12 +55,14 @@ class PurgeCommands {
     return purgeMapper.selectAnalysisUuids(query);
   }
 
-  void deleteAnalyses(String rootComponentUuid) {
+  void deleteEventComponentChanges(String rootComponentUuid) {
     profiler.start("deleteAnalyses (event_component_changes)");
     purgeMapper.deleteEventComponentChangesByComponentUuid(rootComponentUuid);
     session.commit();
     profiler.stop();
+  }
 
+  void deleteAnalyses(String rootComponentUuid) {
     profiler.start("deleteAnalyses (events)");
     purgeMapper.deleteEventsByComponentUuid(rootComponentUuid);
     session.commit();
@@ -255,9 +257,9 @@ class PurgeCommands {
     profiler.stop();
   }
 
-  void deleteOutdatedProperties(String branchUuid) {
+  void deleteOutdatedProperties(String entityUuid) {
     profiler.start("deleteOutdatedProperties (properties)");
-    purgeMapper.deletePropertiesByEntityUuids(List.of(branchUuid));
+    purgeMapper.deletePropertiesByEntityUuids(List.of(entityUuid));
     session.commit();
     profiler.stop();
   }
@@ -454,9 +456,16 @@ class PurgeCommands {
     profiler.stop();
   }
 
-  void deleteNewCodePeriods(String rootUuid) {
+  void deleteNewCodePeriodsForProject(String projectUuid) {
+    profiler.start("deleteNewCodePeriods (new_code_periods)");
+    purgeMapper.deleteNewCodePeriodsByProjectUuid(projectUuid);
+    session.commit();
+    profiler.stop();
+  }
+
+  void deleteNewCodePeriodsForBranch(String branchUuid) {
     profiler.start("deleteNewCodePeriods (new_code_periods)");
-    purgeMapper.deleteNewCodePeriodsByRootUuid(rootUuid);
+    purgeMapper.deleteNewCodePeriodsByBranchUuid(branchUuid);
     session.commit();
     profiler.stop();
   }
@@ -480,9 +489,9 @@ class PurgeCommands {
     profiler.stop();
   }
 
-  public void deleteScannerCache(String rootUuid) {
+  public void deleteScannerCache(String branchUuid) {
     profiler.start("deleteScannerCache (scanner_analysis_cache)");
-    purgeMapper.deleteScannerAnalysisCacheByBranchUuid(rootUuid);
+    purgeMapper.deleteScannerAnalysisCacheByBranchUuid(branchUuid);
     session.commit();
     profiler.stop();
   }
@@ -494,9 +503,9 @@ class PurgeCommands {
     profiler.stop();
   }
 
-  public void deleteReportSubscriptions(String rootUuid) {
+  public void deleteReportSubscriptions(String branchUuid) {
     profiler.start("deleteReportSubscriptions (report_subscriptions)");
-    purgeMapper.deleteReportSubscriptionsByBranchUuid(rootUuid);
+    purgeMapper.deleteReportSubscriptionsByBranchUuid(branchUuid);
     session.commit();
     profiler.stop();
   }
index a1bcec6137e5fd6ca128ad1e2bc2cdc798756f9d..5fd2500d37f61fcb266856ec9688f0c5abf18a26 100644 (file)
@@ -91,7 +91,7 @@ public class PurgeDao implements Dao {
 
     for (String branchUuid : branchUuids) {
       if (!rootUuid.equals(branchUuid)) {
-        deleteRootComponent(branchUuid, mapper, commands);
+        deleteBranch(branchUuid, commands);
       }
     }
   }
@@ -225,9 +225,8 @@ public class PurgeDao implements Dao {
 
   public void deleteBranch(DbSession session, String uuid) {
     PurgeProfiler profiler = new PurgeProfiler();
-    PurgeMapper purgeMapper = mapper(session);
     PurgeCommands purgeCommands = new PurgeCommands(session, profiler, system2);
-    deleteRootComponent(uuid, purgeMapper, purgeCommands);
+    deleteBranch(uuid, purgeCommands);
   }
 
   public void deleteProject(DbSession session, String uuid, String qualifier, String name, String key) {
@@ -242,9 +241,9 @@ public class PurgeDao implements Dao {
       .map(BranchDto::getUuid)
       .toList();
 
-    branchUuids.forEach(id -> deleteRootComponent(id, purgeMapper, purgeCommands));
+    branchUuids.forEach(id -> deleteBranch(id, purgeCommands));
 
-    deleteRootComponent(uuid, purgeMapper, purgeCommands);
+    deleteProject(uuid, purgeMapper, purgeCommands);
     auditPersister.deleteComponent(session, new ComponentNewValue(uuid, name, key, qualifier));
     logProfiling(profiler, start);
   }
@@ -265,35 +264,52 @@ public class PurgeDao implements Dao {
     LOG.debug("");
   }
 
-  private static void deleteRootComponent(String rootUuid, PurgeMapper mapper, PurgeCommands commands) {
-    List<String> rootAndSubviews = mapper.selectRootAndSubviewsByProjectUuid(rootUuid);
-    commands.deleteLinks(rootUuid);
-    commands.deleteScannerCache(rootUuid);
-    commands.deleteAnalyses(rootUuid);
+  private static void deleteBranch(String branchUuid, PurgeCommands commands) {
+    commands.deleteScannerCache(branchUuid);
+    commands.deleteAnalyses(branchUuid);
+    commands.deleteIssues(branchUuid);
+    commands.deleteFileSources(branchUuid);
+    commands.deleteCeActivity(branchUuid);
+    commands.deleteCeQueue(branchUuid);
+    commands.deleteLiveMeasures(branchUuid);
+    commands.deleteNewCodePeriodsForBranch(branchUuid);
+    commands.deleteBranch(branchUuid);
+    commands.deleteApplicationBranchProjects(branchUuid);
+    commands.deleteComponents(branchUuid);
+    commands.deleteReportSchedules(branchUuid);
+    commands.deleteReportSubscriptions(branchUuid);
+  }
+
+  private static void deleteProject(String projectUuid, PurgeMapper mapper, PurgeCommands commands) {
+    List<String> rootAndSubviews = mapper.selectRootAndSubviewsByProjectUuid(projectUuid);
+    commands.deleteLinks(projectUuid);
+    commands.deleteScannerCache(projectUuid);
+    commands.deleteEventComponentChanges(projectUuid);
+    commands.deleteAnalyses(projectUuid);
     commands.deleteByRootAndSubviews(rootAndSubviews);
-    commands.deleteIssues(rootUuid);
-    commands.deleteFileSources(rootUuid);
-    commands.deleteCeActivity(rootUuid);
-    commands.deleteCeQueue(rootUuid);
-    commands.deleteWebhooks(rootUuid);
-    commands.deleteWebhookDeliveries(rootUuid);
-    commands.deleteLiveMeasures(rootUuid);
-    commands.deleteProjectAlmSettings(rootUuid);
-    commands.deletePermissions(rootUuid);
-    commands.deleteNewCodePeriods(rootUuid);
-    commands.deleteBranch(rootUuid);
-    commands.deleteApplicationBranchProjects(rootUuid);
-    commands.deleteApplicationProjects(rootUuid);
-    commands.deleteApplicationProjectsByProject(rootUuid);
-    commands.deleteProjectInPortfolios(rootUuid);
-    commands.deleteComponents(rootUuid);
-    commands.deleteNonMainBranchComponentsByProjectUuid(rootUuid);
-    commands.deleteProjectBadgeToken(rootUuid);
-    commands.deleteProject(rootUuid);
-    commands.deleteUserDismissedMessages(rootUuid);
-    commands.deleteOutdatedProperties(rootUuid);
-    commands.deleteReportSchedules(rootUuid);
-    commands.deleteReportSubscriptions(rootUuid);
+    commands.deleteIssues(projectUuid);
+    commands.deleteFileSources(projectUuid);
+    commands.deleteCeActivity(projectUuid);
+    commands.deleteCeQueue(projectUuid);
+    commands.deleteWebhooks(projectUuid);
+    commands.deleteWebhookDeliveries(projectUuid);
+    commands.deleteLiveMeasures(projectUuid);
+    commands.deleteProjectAlmSettings(projectUuid);
+    commands.deletePermissions(projectUuid);
+    commands.deleteNewCodePeriodsForProject(projectUuid);
+    commands.deleteBranch(projectUuid);
+    commands.deleteApplicationBranchProjects(projectUuid);
+    commands.deleteApplicationProjects(projectUuid);
+    commands.deleteApplicationProjectsByProject(projectUuid);
+    commands.deleteProjectInPortfolios(projectUuid);
+    commands.deleteComponents(projectUuid);
+    commands.deleteNonMainBranchComponentsByProjectUuid(projectUuid);
+    commands.deleteProjectBadgeToken(projectUuid);
+    commands.deleteProject(projectUuid);
+    commands.deleteUserDismissedMessages(projectUuid);
+    commands.deleteOutdatedProperties(projectUuid);
+    commands.deleteReportSchedules(projectUuid);
+    commands.deleteReportSubscriptions(projectUuid);
   }
 
   /**
index 9f702aec832cd67457e867eb5ac3ba58c595c0b2..34c6378a75bae38eceeb0a03e5a5feccfe4e5645 100644 (file)
@@ -171,7 +171,9 @@ public interface PurgeMapper {
 
   void deleteLiveMeasuresByComponentUuids(@Param("componentUuids") List<String> componentUuids);
 
-  void deleteNewCodePeriodsByRootUuid(String rootUuid);
+  void deleteNewCodePeriodsByProjectUuid(String projectUuid);
+
+  void deleteNewCodePeriodsByBranchUuid(String branchUuid);
 
   void deleteProjectAlmSettingsByProjectUuid(@Param("projectUuid") String projectUuid);
 
index e29021fe997d7f74e76cff6f7920e4ce0abbf734..807f9d1ac6d1053d5067a2ca55e817d24649174f 100644 (file)
       or entity_uuid=#{rootUuid,jdbcType=VARCHAR}
   </delete>
 
-  <delete id="deleteNewCodePeriodsByRootUuid">
+  <delete id="deleteNewCodePeriodsByProjectUuid">
     DELETE FROM new_code_periods
     WHERE
-      branch_uuid=#{rootUuid,jdbcType=VARCHAR}
-      OR project_uuid=#{rootUuid,jdbcType=VARCHAR}
+      project_uuid=#{projectUuid,jdbcType=VARCHAR}
+  </delete>
+
+  <delete id="deleteNewCodePeriodsByBranchUuid">
+    DELETE FROM new_code_periods
+    WHERE
+      branch_uuid=#{branchUuid,jdbcType=VARCHAR}
   </delete>
 
   <delete id="deleteWebhooksByProjectUuid">