*/
package org.sonar.ce.task.projectanalysis.purge;
-import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
-import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Predicate;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.ce.task.projectanalysis.component.ViewsComponent;
import org.sonar.ce.task.projectanalysis.step.BaseStepTest;
+import org.sonar.ce.task.projectanalysis.util.WrapInSingleElementArray;
import org.sonar.ce.task.step.ComputationStep;
import org.sonar.ce.task.step.TestComputationStepContext;
import org.sonar.db.DbClient;
import org.sonar.server.project.Project;
-import org.sonar.ce.task.projectanalysis.util.WrapInSingleElementArray;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@RunWith(DataProviderRunner.class)
verify_call_purge_method_of_the_purge_task(project);
}
-
- @DataProvider
- public static Object[][] nonRootProjectComponentTypes() {
- return dataproviderFromComponentTypeValues(input -> input.isReportType() && input != Component.Type.PROJECT);
- }
-
- @Test
- @UseDataProvider("nonRootProjectComponentTypes")
- public void do_not_call_purge_method_of_the_purge_task_for_other_report_components(Component.Type type) {
- Component component = ReportComponent.builder(type, 1).setUuid(PROJECT_UUID).setKey(PROJECT_KEY).build();
-
- verify_do_not_call_purge_method_of_the_purge_task(component);
- }
-
- @DataProvider
- public static Object[][] nonRootViewsComponentTypes() {
- return dataproviderFromComponentTypeValues(input -> input.isViewsType() && input != Component.Type.VIEW);
- }
-
- @Test
- @UseDataProvider("nonRootViewsComponentTypes")
- public void do_not_call_purge_method_of_the_purge_task_for_other_views_components(Component.Type type) {
- Component component = ViewsComponent.builder(type, PROJECT_KEY).setUuid(PROJECT_UUID).build();
-
- verify_do_not_call_purge_method_of_the_purge_task(component);
- }
-
- private void verify_do_not_call_purge_method_of_the_purge_task(Component component) {
- treeRootHolder.setRoot(component);
-
- underTest.execute(new TestComputationStepContext());
-
- verifyNoMoreInteractions(projectCleaner);
- }
-
+
private void verify_call_purge_method_of_the_purge_task(Component project) {
treeRootHolder.setRoot(project);
when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().asConfig());
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.sonar.api.utils.System2;
import org.sonar.db.DbSession;
this(session, session.getMapper(PurgeMapper.class), profiler, system2);
}
- List<String> selectSnapshotUuids(PurgeSnapshotQuery query) {
- return purgeMapper.selectAnalysisIdsAndUuids(query).stream().map(IdUuidPair::getUuid).collect(Collectors.toList());
- }
-
List<IdUuidPair> selectSnapshotIdUuids(PurgeSnapshotQuery query) {
return purgeMapper.selectAnalysisIdsAndUuids(query);
}
profiler.stop();
}
- void deleteComponentMeasures(List<String> analysisUuids, List<String> componentUuids) {
- if (analysisUuids.isEmpty() || componentUuids.isEmpty()) {
- return;
- }
-
- List<List<String>> analysisUuidsPartitions = Lists.partition(analysisUuids, MAX_SNAPSHOTS_PER_QUERY);
- List<List<String>> componentUuidsPartitions = Lists.partition(componentUuids, MAX_RESOURCES_PER_QUERY);
-
- profiler.start("deleteComponentMeasures");
- for (List<String> analysisUuidsPartition : analysisUuidsPartitions) {
- for (List<String> componentUuidsPartition : componentUuidsPartitions) {
- purgeMapper.deleteComponentMeasures(analysisUuidsPartition, componentUuidsPartition);
- }
- }
- session.commit();
- profiler.stop();
- }
-
void deleteFileSources(String rootUuid) {
profiler.start("deleteFileSources (file_sources)");
purgeMapper.deleteFileSourcesByProjectUuid(rootUuid);
package org.sonar.db.purge;
import com.google.common.annotations.VisibleForTesting;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.Date;
import java.util.Optional;
import java.util.Set;
import javax.annotation.CheckForNull;
import org.sonar.api.config.Configuration;
-import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
import org.sonar.core.config.PurgeConstants;
private final String rootUuid;
private final String projectUuid;
- private final Collection<String> scopesWithoutHistoricalData;
private final int maxAgeInDaysOfClosedIssues;
private final Optional<Integer> maxAgeInDaysOfInactiveBranches;
private final System2 system2;
private final Set<String> disabledComponentUuids;
- public PurgeConfiguration(String rootUuid, String projectUuid, Collection<String> scopesWithoutHistoricalData, int maxAgeInDaysOfClosedIssues,
+ public PurgeConfiguration(String rootUuid, String projectUuid, int maxAgeInDaysOfClosedIssues,
Optional<Integer> maxAgeInDaysOfInactiveBranches, System2 system2, Set<String> disabledComponentUuids) {
this.rootUuid = rootUuid;
this.projectUuid = projectUuid;
- this.scopesWithoutHistoricalData = scopesWithoutHistoricalData;
this.maxAgeInDaysOfClosedIssues = maxAgeInDaysOfClosedIssues;
this.system2 = system2;
this.disabledComponentUuids = disabledComponentUuids;
}
public static PurgeConfiguration newDefaultPurgeConfiguration(Configuration config, String rootUuid, String projectUuid, Set<String> disabledComponentUuids) {
- return new PurgeConfiguration(rootUuid, projectUuid, Arrays.asList(Scopes.DIRECTORY, Scopes.FILE), config.getInt(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES).get(),
+ return new PurgeConfiguration(rootUuid, projectUuid, config.getInt(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES).get(),
config.getInt(PurgeConstants.DAYS_BEFORE_DELETING_INACTIVE_BRANCHES_AND_PRS), System2.INSTANCE, disabledComponentUuids);
}
return projectUuid;
}
- public Collection<String> getScopesWithoutHistoricalData() {
- return scopesWithoutHistoricalData;
- }
-
public Set<String> getDisabledComponentUuids() {
return disabledComponentUuids;
}
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
import org.sonar.db.component.BranchMapper;
-import org.sonar.db.component.ComponentDao;
import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTreeQuery;
-import org.sonar.db.component.ComponentTreeQuery.Strategy;
import static java.util.Collections.emptyList;
import static java.util.Optional.ofNullable;
private static final Set<String> QUALIFIERS_MODULE_SUBVIEW = ImmutableSet.of("BRC", "SVW");
private static final String SCOPE_PROJECT = "PRJ";
- private final ComponentDao componentDao;
private final System2 system2;
- public PurgeDao(ComponentDao componentDao, System2 system2) {
- this.componentDao = componentDao;
+ public PurgeDao(System2 system2) {
this.system2 = system2;
}
PurgeCommands commands = new PurgeCommands(session, mapper, profiler, system2);
String rootUuid = conf.rootUuid();
deleteAbortedAnalyses(rootUuid, commands);
- deleteDataOfComponentsWithoutHistoricalData(session, rootUuid, conf.getScopesWithoutHistoricalData(), commands);
purgeAnalyses(commands, rootUuid);
purgeDisabledComponents(commands, conf, listener);
deleteOldClosedIssues(conf, mapper, listener);
commands.deleteAbortedAnalyses(rootUuid);
}
- private void deleteDataOfComponentsWithoutHistoricalData(DbSession dbSession, String rootUuid, Collection<String> scopesWithoutHistoricalData, PurgeCommands purgeCommands) {
- if (scopesWithoutHistoricalData.isEmpty()) {
- return;
- }
-
- List<String> analysisUuids = purgeCommands.selectSnapshotUuids(
- new PurgeSnapshotQuery(rootUuid)
- .setIslast(false)
- .setNotPurged(true));
- List<String> componentWithoutHistoricalDataUuids = componentDao
- .selectDescendants(
- dbSession,
- ComponentTreeQuery.builder()
- .setBaseUuid(rootUuid)
- .setScopes(scopesWithoutHistoricalData)
- .setStrategy(Strategy.LEAVES)
- .build())
- .stream().map(ComponentDto::uuid)
- .collect(MoreCollectors.toList());
-
- purgeCommands.deleteComponentMeasures(analysisUuids, componentWithoutHistoricalDataUuids);
- }
-
private static void deleteOldDisabledComponents(PurgeCommands commands, PurgeMapper mapper, String rootUuid) {
List<IdUuidPair> disabledComponentsWithoutIssue = mapper.selectDisabledComponentsWithoutIssues(rootUuid);
commands.deleteDisabledComponentsWithoutIssues(disabledComponentsWithoutIssue);
void fullDeleteComponentMeasures(@Param("componentUuids") List<String> componentUuids);
- void deleteComponentMeasures(@Param("analysisUuids") List<String> analysisUuids, @Param("componentUuids") List<String> componentUuids);
-
List<Long> selectMetricIdsWithoutHistoricalData();
void deleteAnalysisWastedMeasures(@Param("analysisUuids") List<String> analysisUuids, @Param("metricIds") List<Long> metricIds);
</foreach>
</delete>
- <delete id="deleteComponentMeasures" parameterType="map">
- delete from project_measures
- where
- analysis_uuid in
- <foreach collection="analysisUuids" open="(" close=")" item="analysisUuid" separator=",">
- #{analysisUuid,jdbcType=VARCHAR}
- </foreach>
- and component_uuid in
- <foreach collection="componentUuids" open="(" close=")" item="componentUuid" separator=",">
- #{componentUuid,jdbcType=VARCHAR}
- </foreach>
- </delete>
-
<delete id="deleteAnalysisDuplications" parameterType="map">
delete from duplications_index
where
import java.util.Date;
import java.util.Optional;
import org.junit.Test;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
-import org.sonar.core.config.PurgeConstants;
-import org.sonar.core.config.PurgeProperties;
import static java.util.Collections.emptySet;
import static org.assertj.core.api.Assertions.assertThat;
public class PurgeConfigurationTest {
@Test
public void should_delete_all_closed_issues() {
- PurgeConfiguration conf = new PurgeConfiguration("root", "project", emptySet(), 0, Optional.empty(), System2.INSTANCE, emptySet());
+ PurgeConfiguration conf = new PurgeConfiguration("root", "project", 0, Optional.empty(), System2.INSTANCE, emptySet());
assertThat(conf.maxLiveDateOfClosedIssues()).isNull();
- conf = new PurgeConfiguration("root", "project", emptySet(), -1, Optional.empty(), System2.INSTANCE, emptySet());
+ conf = new PurgeConfiguration("root", "project", -1, Optional.empty(), System2.INSTANCE, emptySet());
assertThat(conf.maxLiveDateOfClosedIssues()).isNull();
}
public void should_delete_only_old_closed_issues() {
Date now = DateUtils.parseDate("2013-05-18");
- PurgeConfiguration conf = new PurgeConfiguration("root", "project", emptySet(), 30, Optional.empty(), System2.INSTANCE, emptySet());
+ PurgeConfiguration conf = new PurgeConfiguration("root", "project", 30, Optional.empty(), System2.INSTANCE, emptySet());
Date toDate = conf.maxLiveDateOfClosedIssues(now);
assertThat(toDate.getYear()).isEqualTo(113);// =2013
@Test
public void should_have_empty_branch_purge_date() {
- PurgeConfiguration conf = new PurgeConfiguration("root", "project", emptySet(), 30, Optional.of(10), System2.INSTANCE, emptySet());
+ PurgeConfiguration conf = new PurgeConfiguration("root", "project", 30, Optional.of(10), System2.INSTANCE, emptySet());
assertThat(conf.maxLiveDateOfInactiveBranches()).isNotEmpty();
long tenDaysAgo = DateUtils.addDays(new Date(System2.INSTANCE.now()), -10).getTime();
assertThat(conf.maxLiveDateOfInactiveBranches().get().getTime()).isBetween(tenDaysAgo - 5000, tenDaysAgo + 5000);
@Test
public void should_calculate_branch_purge_date() {
- PurgeConfiguration conf = new PurgeConfiguration("root", "project", emptySet(), 30, Optional.empty(), System2.INSTANCE, emptySet());
+ PurgeConfiguration conf = new PurgeConfiguration("root", "project", 30, Optional.empty(), System2.INSTANCE, emptySet());
assertThat(conf.maxLiveDateOfInactiveBranches()).isEmpty();
}
- @Test
- public void delete_files_and_directories() {
- MapSettings settings = new MapSettings(new PropertyDefinitions(PurgeProperties.all()));
- settings.setProperty(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES, 5);
- Date now = new Date();
-
- PurgeConfiguration underTest = PurgeConfiguration.newDefaultPurgeConfiguration(settings.asConfig(), "root", "project", emptySet());
-
- assertThat(underTest.getScopesWithoutHistoricalData())
- .containsExactlyInAnyOrder(Scopes.DIRECTORY, Scopes.FILE);
- assertThat(underTest.maxLiveDateOfClosedIssues(now)).isEqualTo(DateUtils.addDays(now, -5));
- }
}
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.issue.Issue;
-import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.System2;
import org.sonar.core.util.CloseableIterator;
import org.sonar.core.util.UuidFactoryFast;
import static com.google.common.base.MoreObjects.firstNonNull;
import static java.time.ZoneOffset.UTC;
import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static java.util.Collections.singletonList;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
}
@Test
- public void shouldDeleteHistoricalDataOfDirectoriesAndFiles() {
+ public void shouldDeleteNonHistoricalData() {
MetricDto metricWithHistory = db.measures().insertMetric(t -> t.setDeleteHistoricalData(false));
MetricDto metricWithoutHistory = db.measures().insertMetric(t -> t.setDeleteHistoricalData(true));
ComponentDto project = db.components().insertPrivateProject();
db.measures().insertMeasure(otherProject, otherOldAnalysis, metricWithHistory);
db.measures().insertMeasure(otherProject, otherOldAnalysis, metricWithoutHistory);
- PurgeConfiguration conf = new PurgeConfiguration(project.uuid(), project.uuid(), asList(Scopes.DIRECTORY, Scopes.FILE),
- 30, Optional.of(30), System2.INSTANCE, emptySet());
+ PurgeConfiguration conf = new PurgeConfiguration(project.uuid(), project.uuid(), 30, Optional.of(30), System2.INSTANCE, emptySet());
underTest.purge(dbSession, conf, PurgeListener.EMPTY, new PurgeProfiler());
dbSession.commit();
}
private static PurgeConfiguration newConfigurationWith30Days(String rootUuid) {
- return new PurgeConfiguration(rootUuid, rootUuid, emptyList(), 30, Optional.of(30), System2.INSTANCE, emptySet());
+ return new PurgeConfiguration(rootUuid, rootUuid, 30, Optional.of(30), System2.INSTANCE, emptySet());
}
private static PurgeConfiguration newConfigurationWith30Days(System2 system2, String rootUuid, String projectUuid) {
}
private static PurgeConfiguration newConfigurationWith30Days(System2 system2, String rootUuid, String projectUuid, Set<String> disabledComponentUuids) {
- return new PurgeConfiguration(rootUuid, projectUuid, emptyList(), 30, Optional.of(30), system2, disabledComponentUuids);
+ return new PurgeConfiguration(rootUuid, projectUuid, 30, Optional.of(30), system2, disabledComponentUuids);
}
private Stream<String> uuidsOfAnalysesOfRoot(ComponentDto rootComponent) {