Browse Source

SONAR-11439 Analysis of long branch doesn't trigger purge of dependent short branches and pull requests

tags/7.7
Duarte Meneses 5 years ago
parent
commit
01f2c2e66d

+ 3
- 4
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/purge/ProjectCleaner.java View File

@@ -28,7 +28,6 @@ import org.sonar.api.utils.TimeUtils;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.DbSession;
import org.sonar.db.purge.IdUuidPair;
import org.sonar.db.purge.PurgeConfiguration;
import org.sonar.db.purge.PurgeDao;
import org.sonar.db.purge.PurgeListener;
@@ -54,13 +53,13 @@ public class ProjectCleaner {
this.purgeListener = purgeListener;
}

public ProjectCleaner purge(DbSession session, IdUuidPair rootId, Configuration projectConfig, Collection<String> disabledComponentUuids) {
public ProjectCleaner purge(DbSession session, String rootUuid, String projectUuid, Configuration projectConfig, Collection<String> disabledComponentUuids) {
long start = System.currentTimeMillis();
profiler.reset();

PurgeConfiguration configuration = newDefaultPurgeConfiguration(projectConfig, rootId, disabledComponentUuids);
periodCleaner.clean(session, rootUuid, projectConfig);

periodCleaner.clean(session, configuration.rootProjectIdUuid().getUuid(), projectConfig);
PurgeConfiguration configuration = newDefaultPurgeConfiguration(projectConfig, rootUuid, projectUuid, disabledComponentUuids);
purgeDao.purge(session, configuration, purgeListener, profiler);

session.commit();

+ 7
- 8
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/purge/PurgeDatastoresStep.java View File

@@ -19,9 +19,9 @@
*/
package org.sonar.ce.task.projectanalysis.purge;

import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository;
import org.sonar.ce.task.projectanalysis.component.DbIdsRepository;
import org.sonar.ce.task.projectanalysis.component.DepthTraversalTypeAwareCrawler;
import org.sonar.ce.task.projectanalysis.component.DisabledComponentsHolder;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolder;
@@ -29,7 +29,6 @@ import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitorAdapter;
import org.sonar.ce.task.step.ComputationStep;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.purge.IdUuidPair;

import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW;
@@ -40,19 +39,19 @@ public class PurgeDatastoresStep implements ComputationStep {

private final ProjectCleaner projectCleaner;
private final DbClient dbClient;
private final DbIdsRepository dbIdsRepository;
private final TreeRootHolder treeRootHolder;
private final ConfigurationRepository configRepository;
private final DisabledComponentsHolder disabledComponentsHolder;
private final AnalysisMetadataHolder analysisMetadataHolder;

public PurgeDatastoresStep(DbClient dbClient, ProjectCleaner projectCleaner, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder,
ConfigurationRepository configRepository, DisabledComponentsHolder disabledComponentsHolder) {
public PurgeDatastoresStep(DbClient dbClient, ProjectCleaner projectCleaner, TreeRootHolder treeRootHolder,
ConfigurationRepository configRepository, DisabledComponentsHolder disabledComponentsHolder, AnalysisMetadataHolder analysisMetadataHolder) {
this.projectCleaner = projectCleaner;
this.dbClient = dbClient;
this.dbIdsRepository = dbIdsRepository;
this.treeRootHolder = treeRootHolder;
this.configRepository = configRepository;
this.disabledComponentsHolder = disabledComponentsHolder;
this.analysisMetadataHolder = analysisMetadataHolder;
}

@Override
@@ -73,8 +72,8 @@ public class PurgeDatastoresStep implements ComputationStep {

private void execute(Component root) {
try (DbSession dbSession = dbClient.openSession(true)) {
IdUuidPair idUuidPair = new IdUuidPair(dbIdsRepository.getComponentId(root), root.getUuid());
projectCleaner.purge(dbSession, idUuidPair, configRepository.getConfiguration(), disabledComponentsHolder.getUuids());
String projectUuid = analysisMetadataHolder.getProject().getUuid();
projectCleaner.purge(dbSession, root.getUuid(), projectUuid, configRepository.getConfiguration(), disabledComponentsHolder.getUuids());
dbSession.commit();
}
}

+ 4
- 7
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/duplication/DuplicationRepositoryImplTest.java View File

@@ -32,9 +32,6 @@ import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.ReportComponent;
import org.sonar.server.util.WrapInSingleElementArray;

import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.FluentIterable.from;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -138,10 +135,10 @@ public class DuplicationRepositoryImplTest {

@DataProvider
public static Object[][] allComponentTypesButFile() {
return from(Arrays.asList(Component.Type.values()))
.filter(not(equalTo(Component.Type.FILE)))
.transform(WrapInSingleElementArray.INSTANCE)
.toArray(Object[].class);
return Arrays.stream(Component.Type.values())
.filter(t -> t != Component.Type.FILE)
.map(WrapInSingleElementArray.INSTANCE)
.toArray(Object[][]::new);
}

private void assertNoDuplication(Component component) {

+ 5
- 5
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/MeasureTest.java View File

@@ -33,7 +33,6 @@ import org.sonar.ce.task.projectanalysis.component.DumbDeveloper;
import org.sonar.ce.task.projectanalysis.measure.Measure.ValueType;
import org.sonar.server.util.WrapInSingleElementArray;

import static com.google.common.collect.FluentIterable.from;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;

@@ -88,13 +87,14 @@ public class MeasureTest {

@DataProvider
public static Object[][] all() {
return from(MEASURES).transform(WrapInSingleElementArray.INSTANCE).toArray(Object[].class);
return MEASURES.stream().map(WrapInSingleElementArray.INSTANCE).toArray(Object[][]::new);
}

private static Object[][] getMeasuresExcept(final ValueType valueType) {
return from(MEASURES)
.filter(input -> input.getValueType() != valueType).transform(WrapInSingleElementArray.INSTANCE)
.toArray(Object[].class);
return MEASURES.stream()
.filter(input -> input.getValueType() != valueType)
.map(WrapInSingleElementArray.INSTANCE)
.toArray(Object[][]::new);
}

@Test

+ 3
- 4
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/purge/ProjectCleanerTest.java View File

@@ -27,7 +27,6 @@ import org.sonar.api.config.internal.MapSettings;
import org.sonar.core.config.PurgeConstants;
import org.sonar.core.config.PurgeProperties;
import org.sonar.db.DbSession;
import org.sonar.db.purge.IdUuidPair;
import org.sonar.db.purge.PurgeDao;
import org.sonar.db.purge.PurgeListener;
import org.sonar.db.purge.PurgeProfiler;
@@ -58,7 +57,7 @@ public class ProjectCleanerTest {
public void no_profiling_when_property_is_false() {
settings.setProperty(CoreProperties.PROFILING_LOG_PROPERTY, false);

underTest.purge(mock(DbSession.class), mock(IdUuidPair.class), settings.asConfig(), emptyList());
underTest.purge(mock(DbSession.class), "root", "project", settings.asConfig(), emptyList());

verify(profiler, never()).dump(anyLong(), any());
}
@@ -67,7 +66,7 @@ public class ProjectCleanerTest {
public void profiling_when_property_is_true() {
settings.setProperty(CoreProperties.PROFILING_LOG_PROPERTY, true);

underTest.purge(mock(DbSession.class), mock(IdUuidPair.class), settings.asConfig(), emptyList());
underTest.purge(mock(DbSession.class), "root", "project", settings.asConfig(), emptyList());

verify(profiler).dump(anyLong(), any());
}
@@ -76,7 +75,7 @@ public class ProjectCleanerTest {
public void call_period_cleaner_index_client_and_purge_dao() {
settings.setProperty(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES, 5);

underTest.purge(mock(DbSession.class), mock(IdUuidPair.class), settings.asConfig(), emptyList());
underTest.purge(mock(DbSession.class), "root", "project", settings.asConfig(), emptyList());

verify(periodCleaner).clean(any(), any(), any());
verify(dao).purge(any(), any(), any(), any());

+ 23
- 29
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/purge/PurgeDatastoresStepTest.java View File

@@ -19,20 +19,22 @@
*/
package org.sonar.ce.task.projectanalysis.purge;

import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
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.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository;
import org.sonar.ce.task.projectanalysis.component.MutableDbIdsRepositoryRule;
import org.sonar.ce.task.projectanalysis.component.MutableDisabledComponentsHolder;
import org.sonar.ce.task.projectanalysis.component.ReportComponent;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
@@ -41,12 +43,12 @@ import org.sonar.ce.task.projectanalysis.step.BaseStepTest;
import org.sonar.ce.task.step.ComputationStep;
import org.sonar.ce.task.step.TestComputationStepContext;
import org.sonar.db.DbClient;
import org.sonar.db.purge.IdUuidPair;
import org.sonar.server.project.Project;
import org.sonar.server.util.WrapInSingleElementArray;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -57,20 +59,24 @@ import static org.mockito.Mockito.when;
public class PurgeDatastoresStepTest extends BaseStepTest {

private static final String PROJECT_KEY = "PROJECT_KEY";
private static final long PROJECT_ID = 123L;
private static final String PROJECT_UUID = "UUID-1234";

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
@Rule
public MutableDbIdsRepositoryRule dbIdsRepository = MutableDbIdsRepositoryRule.standalone();
public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();

private ProjectCleaner projectCleaner = mock(ProjectCleaner.class);
private ConfigurationRepository settingsRepository = mock(ConfigurationRepository.class);
private MutableDisabledComponentsHolder disabledComponentsHolder = mock(MutableDisabledComponentsHolder.class, RETURNS_DEEP_STUBS);

private PurgeDatastoresStep underTest = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner, dbIdsRepository, treeRootHolder,
settingsRepository, disabledComponentsHolder);
private PurgeDatastoresStep underTest = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner, treeRootHolder,
settingsRepository, disabledComponentsHolder, analysisMetadataHolder);

@Before
public void before() {
analysisMetadataHolder.setProject(new Project("uuid", "key", "name", null, Collections.emptyList()));
}

@Test
public void call_purge_method_of_the_purge_task_for_project() {
@@ -88,12 +94,7 @@ public class PurgeDatastoresStepTest extends BaseStepTest {

@DataProvider
public static Object[][] nonRootProjectComponentTypes() {
return dataproviderFromComponentTypeValues(new Predicate<Component.Type>() {
@Override
public boolean apply(Component.Type input) {
return input.isReportType() && input != Component.Type.PROJECT;
}
});
return dataproviderFromComponentTypeValues(input -> input.isReportType() && input != Component.Type.PROJECT);
}

@Test
@@ -106,12 +107,7 @@ public class PurgeDatastoresStepTest extends BaseStepTest {

@DataProvider
public static Object[][] nonRootViewsComponentTypes() {
return dataproviderFromComponentTypeValues(new Predicate<Component.Type>() {
@Override
public boolean apply(Component.Type input) {
return input.isViewsType() && input != Component.Type.VIEW;
}
});
return dataproviderFromComponentTypeValues(input -> input.isViewsType() && input != Component.Type.VIEW);
}

@Test
@@ -133,21 +129,19 @@ public class PurgeDatastoresStepTest extends BaseStepTest {
private void verify_call_purge_method_of_the_purge_task(Component project) {
treeRootHolder.setRoot(project);
when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().asConfig());
dbIdsRepository.setComponentId(project, PROJECT_ID);

underTest.execute(new TestComputationStepContext());

ArgumentCaptor<IdUuidPair> argumentCaptor = ArgumentCaptor.forClass(IdUuidPair.class);
verify(projectCleaner).purge(any(), argumentCaptor.capture(), any(), any());
assertThat(argumentCaptor.getValue().getId()).isEqualTo(PROJECT_ID);
assertThat(argumentCaptor.getValue().getUuid()).isEqualTo(PROJECT_UUID);
ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
verify(projectCleaner).purge(any(), argumentCaptor.capture(), anyString(), any(), any());
assertThat(argumentCaptor.getValue()).isEqualTo(PROJECT_UUID);
}

private static Object[][] dataproviderFromComponentTypeValues(Predicate<Component.Type> predicate) {
return FluentIterable.from(asList(Component.Type.values()))
return Arrays.stream(Component.Type.values())
.filter(predicate)
.transform(WrapInSingleElementArray.INSTANCE)
.toArray(Object[].class);
.map(WrapInSingleElementArray.INSTANCE)
.toArray(Object[][]::new);
}

@Override

+ 21
- 7
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeConfiguration.java View File

@@ -33,16 +33,18 @@ import org.sonar.core.config.PurgeConstants;

public class PurgeConfiguration {

private final IdUuidPair rootProjectIdUuid;
private final String rootUuid;
private final String projectUuid;
private final Collection<String> scopesWithoutHistoricalData;
private final int maxAgeInDaysOfClosedIssues;
private final Optional<Integer> maxAgeInDaysOfInactiveShortLivingBranches;
private final System2 system2;
private final Collection<String> disabledComponentUuids;

public PurgeConfiguration(IdUuidPair rootProjectId, Collection<String> scopesWithoutHistoricalData, int maxAgeInDaysOfClosedIssues,
public PurgeConfiguration(String rootUuid, String projectUuid, Collection<String> scopesWithoutHistoricalData, int maxAgeInDaysOfClosedIssues,
Optional<Integer> maxAgeInDaysOfInactiveShortLivingBranches, System2 system2, Collection<String> disabledComponentUuids) {
this.rootProjectIdUuid = rootProjectId;
this.rootUuid = rootUuid;
this.projectUuid = projectUuid;
this.scopesWithoutHistoricalData = scopesWithoutHistoricalData;
this.maxAgeInDaysOfClosedIssues = maxAgeInDaysOfClosedIssues;
this.system2 = system2;
@@ -50,13 +52,25 @@ public class PurgeConfiguration {
this.maxAgeInDaysOfInactiveShortLivingBranches = maxAgeInDaysOfInactiveShortLivingBranches;
}

public static PurgeConfiguration newDefaultPurgeConfiguration(Configuration config, IdUuidPair rootId, Collection<String> disabledComponentUuids) {
return new PurgeConfiguration(rootId, Arrays.asList(Scopes.DIRECTORY, Scopes.FILE), config.getInt(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES).get(),
public static PurgeConfiguration newDefaultPurgeConfiguration(Configuration config, String rootUuid, String projectUuid, Collection<String> disabledComponentUuids) {
return new PurgeConfiguration(rootUuid, projectUuid, Arrays.asList(Scopes.DIRECTORY, Scopes.FILE), config.getInt(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES).get(),
config.getInt(PurgeConstants.DAYS_BEFORE_DELETING_INACTIVE_SHORT_LIVING_BRANCHES), System2.INSTANCE, disabledComponentUuids);
}

public IdUuidPair rootProjectIdUuid() {
return rootProjectIdUuid;
/**
* UUID of the branch being analyzed (root of the component tree). Will be the same as {@link #projectUuid}
* if it's the main branch.
* Can also be a view.
*/
public String rootUuid() {
return rootUuid;
}

/**
* @return UUID of the main branch of the project
*/
public String projectUuid() {
return projectUuid;
}

public Collection<String> getScopesWithoutHistoricalData() {

+ 8
- 6
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java View File

@@ -61,7 +61,7 @@ public class PurgeDao implements Dao {
public void purge(DbSession session, PurgeConfiguration conf, PurgeListener listener, PurgeProfiler profiler) {
PurgeMapper mapper = session.getMapper(PurgeMapper.class);
PurgeCommands commands = new PurgeCommands(session, mapper, profiler);
String rootUuid = conf.rootProjectIdUuid().getUuid();
String rootUuid = conf.rootUuid();
deleteAbortedAnalyses(rootUuid, commands);
deleteDataOfComponentsWithoutHistoricalData(session, rootUuid, conf.getScopesWithoutHistoricalData(), commands);
purgeAnalyses(commands, rootUuid);
@@ -78,10 +78,12 @@ public class PurgeDao implements Dao {
}
LOG.debug("<- Purge stale branches");

List<String> branchUuids = mapper.selectStaleShortLivingBranchesAndPullRequests(rootUuid, dateToLong(maxDate.get()));
List<String> branchUuids = mapper.selectStaleShortLivingBranchesAndPullRequests(conf.projectUuid(), dateToLong(maxDate.get()));

for (String branchUuid : branchUuids) {
deleteRootComponent(branchUuid, mapper, commands);
if (!rootUuid.equals(branchUuid)) {
deleteRootComponent(branchUuid, mapper, commands);
}
}
}

@@ -96,7 +98,7 @@ public class PurgeDao implements Dao {

private static void deleteOldClosedIssues(PurgeConfiguration conf, PurgeMapper mapper, PurgeListener listener) {
Date toDate = conf.maxLiveDateOfClosedIssues();
String rootUuid = conf.rootProjectIdUuid().getUuid();
String rootUuid = conf.rootUuid();
List<String> issueKeys = mapper.selectOldClosedIssueKeys(rootUuid, dateToLong(toDate));
executeLargeInputs(issueKeys, input -> {
mapper.deleteIssueChangesFromIssueKeys(input);
@@ -152,7 +154,7 @@ public class PurgeDao implements Dao {
return emptyList();
});

listener.onComponentsDisabling(conf.rootProjectIdUuid().getUuid(), conf.getDisabledComponentUuids());
listener.onComponentsDisabling(conf.rootUuid(), conf.getDisabledComponentUuids());

session.commit();
}
@@ -214,7 +216,7 @@ public class PurgeDao implements Dao {
* Delete the non root components (ie. sub-view, application or project copy) from the specified collection of {@link ComponentDto}
* and data from their child tables.
* <p>
* This method has no effect when passed an empty collection or only root components.
* This method has no effect when passed an empty collection or only root components.
* </p>
*/
public void deleteNonRootComponentsInView(DbSession dbSession, Collection<ComponentDto> components) {

+ 1
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java View File

@@ -84,7 +84,7 @@ public interface PurgeMapper {

List<String> selectOldClosedIssueKeys(@Param("projectUuid") String projectUuid, @Nullable @Param("toDate") Long toDate);

List<String> selectStaleShortLivingBranchesAndPullRequests(@Param("mainBranchProjectUuid") String mainBranchProjectUuid, @Param("toDate") Long toDate);
List<String> selectStaleShortLivingBranchesAndPullRequests(@Param("projectUuid") String projectUuid, @Param("toDate") Long toDate);

void deleteIssuesFromKeys(@Param("keys") List<String> keys);


+ 1
- 1
server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml View File

@@ -52,7 +52,7 @@
from
project_branches pb
where
pb.project_uuid=#{mainBranchProjectUuid,jdbcType=VARCHAR}
pb.project_uuid=#{projectUuid,jdbcType=VARCHAR}
and (pb.branch_type='SHORT' or pb.branch_type='PULL_REQUEST')
and pb.updated_at &lt; #{toDate}
</select>

+ 6
- 6
server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeConfigurationTest.java View File

@@ -36,10 +36,10 @@ import static org.assertj.core.api.Assertions.assertThat;
public class PurgeConfigurationTest {
@Test
public void should_delete_all_closed_issues() {
PurgeConfiguration conf = new PurgeConfiguration(new IdUuidPair(1L, "1"), emptyList(), 0, Optional.empty(), System2.INSTANCE, emptyList());
PurgeConfiguration conf = new PurgeConfiguration("root", "project", emptyList(), 0, Optional.empty(), System2.INSTANCE, emptyList());
assertThat(conf.maxLiveDateOfClosedIssues()).isNull();

conf = new PurgeConfiguration(new IdUuidPair(1L, "1"), emptyList(), -1, Optional.empty(), System2.INSTANCE, emptyList());
conf = new PurgeConfiguration("root", "project", emptyList(), -1, Optional.empty(), System2.INSTANCE, emptyList());
assertThat(conf.maxLiveDateOfClosedIssues()).isNull();
}

@@ -47,7 +47,7 @@ public class PurgeConfigurationTest {
public void should_delete_only_old_closed_issues() {
Date now = DateUtils.parseDate("2013-05-18");

PurgeConfiguration conf = new PurgeConfiguration(new IdUuidPair(1L, "1"), emptyList(), 30, Optional.empty(), System2.INSTANCE, emptyList());
PurgeConfiguration conf = new PurgeConfiguration("root", "project", emptyList(), 30, Optional.empty(), System2.INSTANCE, emptyList());
Date toDate = conf.maxLiveDateOfClosedIssues(now);

assertThat(toDate.getYear()).isEqualTo(113);// =2013
@@ -57,7 +57,7 @@ public class PurgeConfigurationTest {

@Test
public void should_have_empty_branch_purge_date() {
PurgeConfiguration conf = new PurgeConfiguration(new IdUuidPair(1L, "1"), emptyList(), 30, Optional.of(10), System2.INSTANCE, emptyList());
PurgeConfiguration conf = new PurgeConfiguration("root", "project", emptyList(), 30, Optional.of(10), System2.INSTANCE, emptyList());
assertThat(conf.maxLiveDateOfInactiveShortLivingBranches()).isNotEmpty();
long tenDaysAgo = DateUtils.addDays(new Date(System2.INSTANCE.now()), -10).getTime();
assertThat(conf.maxLiveDateOfInactiveShortLivingBranches().get().getTime()).isBetween(tenDaysAgo - 5000, tenDaysAgo + 5000);
@@ -65,7 +65,7 @@ public class PurgeConfigurationTest {

@Test
public void should_calculate_branch_purge_date() {
PurgeConfiguration conf = new PurgeConfiguration(new IdUuidPair(1L, "1"), emptyList(), 30, Optional.empty(), System2.INSTANCE, emptyList());
PurgeConfiguration conf = new PurgeConfiguration("root", "project", emptyList(), 30, Optional.empty(), System2.INSTANCE, emptyList());
assertThat(conf.maxLiveDateOfInactiveShortLivingBranches()).isEmpty();
}

@@ -75,7 +75,7 @@ public class PurgeConfigurationTest {
settings.setProperty(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES, 5);
Date now = new Date();

PurgeConfiguration underTest = PurgeConfiguration.newDefaultPurgeConfiguration(settings.asConfig(), new IdUuidPair(42L, "any-uuid"), emptyList());
PurgeConfiguration underTest = PurgeConfiguration.newDefaultPurgeConfiguration(settings.asConfig(), "root", "project", emptyList());

assertThat(underTest.getScopesWithoutHistoricalData())
.containsExactlyInAnyOrder(Scopes.DIRECTORY, Scopes.FILE);

+ 37
- 11
server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java View File

@@ -90,8 +90,7 @@ import static org.sonar.db.webhook.WebhookDeliveryTesting.selectAllDeliveryUuids

public class PurgeDaoTest {

private static final String THE_PROJECT_UUID = "P1";
private static final long THE_PROJECT_ID = 1L;
private static final String PROJECT_UUID = "P1";

private System2 system2 = mock(System2.class);

@@ -142,7 +141,7 @@ public class PurgeDaoTest {

// back to present
when(system2.now()).thenReturn(new Date().getTime());
underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
dbSession.commit();

assertThat(uuidsIn("projects")).containsOnly(project.uuid(), longBranch.uuid(), recentShortBranch.uuid());
@@ -168,16 +167,43 @@ public class PurgeDaoTest {

// back to present
when(system2.now()).thenReturn(new Date().getTime());
underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
dbSession.commit();

assertThat(uuidsIn("projects")).containsOnly(project.uuid(), longBranch.uuid(), recentPullRequest.uuid());
}

@Test
public void purge_inactive_SLB_when_analyzing_non_main_branch() {
when(system2.now()).thenReturn(new Date().getTime());
RuleDefinitionDto rule = db.rules().insert();
ComponentDto project = db.components().insertMainBranch();
ComponentDto longBranch = db.components().insertProjectBranch(project);

when(system2.now()).thenReturn(DateUtils.addDays(new Date(), -31).getTime());

// SLB updated 31 days ago
ComponentDto slb1 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.SHORT));

// SLB with other components and issues, updated 31 days ago
ComponentDto slb2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST));
ComponentDto file = db.components().insertComponent(newFileDto(slb2));
db.issues().insert(rule, slb2, file);

// back to present
when(system2.now()).thenReturn(new Date().getTime());
// analysing slb1
underTest.purge(dbSession, newConfigurationWith30Days(system2, slb1.uuid(), slb1.getMainBranchProjectUuid()), PurgeListener.EMPTY, new PurgeProfiler());
dbSession.commit();

// slb1 wasn't deleted since it was being analyzed!
assertThat(uuidsIn("projects")).containsOnly(project.uuid(), longBranch.uuid(), slb1.uuid());
}

@Test
public void shouldDeleteHistoricalDataOfDirectoriesAndFiles() {
db.prepareDbUnit(getClass(), "shouldDeleteHistoricalDataOfDirectoriesAndFiles.xml");
PurgeConfiguration conf = new PurgeConfiguration(new IdUuidPair(THE_PROJECT_ID, "PROJECT_UUID"), asList(Scopes.DIRECTORY, Scopes.FILE),
PurgeConfiguration conf = new PurgeConfiguration("PROJECT_UUID", "PROJECT_UUID", asList(Scopes.DIRECTORY, Scopes.FILE),
30, Optional.of(30), System2.INSTANCE, Collections.emptyList());

underTest.purge(dbSession, conf, PurgeListener.EMPTY, new PurgeProfiler());
@@ -231,7 +257,7 @@ public class PurgeDaoTest {

// back to present
when(system2.now()).thenReturn(new Date().getTime());
underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), module.uuid(), dir.uuid(), srcFile.uuid(), testFile.uuid()), PurgeListener.EMPTY,
underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid(), module.uuid(), dir.uuid(), srcFile.uuid(), testFile.uuid()), PurgeListener.EMPTY,
new PurgeProfiler());
dbSession.commit();

@@ -339,7 +365,7 @@ public class PurgeDaoTest {
@Test
public void selectPurgeableAnalyses() {
db.prepareDbUnit(getClass(), "shouldSelectPurgeableAnalysis.xml");
List<PurgeableAnalysisDto> analyses = underTest.selectPurgeableAnalyses(THE_PROJECT_UUID, dbSession);
List<PurgeableAnalysisDto> analyses = underTest.selectPurgeableAnalyses(PROJECT_UUID, dbSession);

assertThat(analyses).hasSize(3);
assertThat(getById(analyses, "u1").isLast()).isTrue();
@@ -869,7 +895,7 @@ public class PurgeDaoTest {
IssueDto notClosed = db.issues().insert(rule, project, file);

when(system2.now()).thenReturn(new Date().getTime());
underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
underTest.purge(dbSession, newConfigurationWith30Days(system2, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
dbSession.commit();

// old closed got deleted
@@ -1251,11 +1277,11 @@ public class PurgeDaoTest {
}

private static PurgeConfiguration newConfigurationWith30Days() {
return new PurgeConfiguration(new IdUuidPair(THE_PROJECT_ID, THE_PROJECT_UUID), emptyList(), 30, Optional.of(30), System2.INSTANCE, Collections.emptyList());
return new PurgeConfiguration(PROJECT_UUID, PROJECT_UUID, emptyList(), 30, Optional.of(30), System2.INSTANCE, Collections.emptyList());
}

private static PurgeConfiguration newConfigurationWith30Days(System2 system2, String rootProjectUuid, String... disabledComponentUuids) {
return new PurgeConfiguration(new IdUuidPair(THE_PROJECT_ID, rootProjectUuid), emptyList(), 30, Optional.of(30), system2, asList(disabledComponentUuids));
private static PurgeConfiguration newConfigurationWith30Days(System2 system2, String rootUuid, String projectUuid, String... disabledComponentUuids) {
return new PurgeConfiguration(rootUuid, projectUuid, emptyList(), 30, Optional.of(30), system2, asList(disabledComponentUuids));
}

}

+ 2
- 2
server/sonar-server/src/test/java/org/sonar/server/util/WrapInSingleElementArray.java View File

@@ -19,7 +19,7 @@
*/
package org.sonar.server.util;

import com.google.common.base.Function;
import java.util.function.Function;
import javax.annotation.Nonnull;

public enum WrapInSingleElementArray implements Function<Object, Object[]> {
@@ -28,6 +28,6 @@ public enum WrapInSingleElementArray implements Function<Object, Object[]> {
@Override
@Nonnull
public Object[] apply(Object input) {
return new Object[]{input};
return new Object[] {input};
}
}

Loading…
Cancel
Save