Browse Source

SONAR-8368 reopen only closed issues closed less than 30 days ago

tags/7.5
Sébastien Lesaint 5 years ago
parent
commit
80549d03ac

+ 19
- 4
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ComponentIssuesLoader.java View File

@@ -20,8 +20,10 @@
package org.sonar.ce.task.projectanalysis.issue;

import com.google.common.collect.ImmutableList;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -29,6 +31,7 @@ import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.utils.System2;
import org.sonar.ce.task.projectanalysis.qualityprofile.ActiveRulesHolder;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.FieldDiffs;
@@ -45,14 +48,18 @@ import static java.util.stream.Collectors.toList;
import static org.sonar.api.issue.Issue.STATUS_CLOSED;

public class ComponentIssuesLoader {
private static final int DEFAULT_CLOSED_ISSUES_MAX_AGE = 30;

private final DbClient dbClient;
private final RuleRepository ruleRepository;
private final ActiveRulesHolder activeRulesHolder;
private final System2 system2;

public ComponentIssuesLoader(DbClient dbClient, RuleRepository ruleRepository, ActiveRulesHolder activeRulesHolder) {
public ComponentIssuesLoader(DbClient dbClient, RuleRepository ruleRepository, ActiveRulesHolder activeRulesHolder, System2 system2) {
this.dbClient = dbClient;
this.activeRulesHolder = activeRulesHolder;
this.ruleRepository = ruleRepository;
this.system2 = system2;
}

public List<DefaultIssue> loadOpenIssues(String componentUuid) {
@@ -136,16 +143,24 @@ public class ComponentIssuesLoader {
* Closed issues do not have a line number in DB (it is unset when the issue is closed), this method
* returns {@link DefaultIssue} objects which line number is populated from the most recent diff logging
* the removal of the line. Closed issues which do not have such diff are not loaded.
* <p>
* To not depend on purge configuration of closed issues, only issues which close date is less than 30 days ago at
* 00H00 are returned.
*/
public List<DefaultIssue> loadClosedIssues(String componentUuid) {
Date date = new Date(system2.now());
long closeDateAfter = date.toInstant()
.minus(DEFAULT_CLOSED_ISSUES_MAX_AGE, ChronoUnit.DAYS)
.truncatedTo(ChronoUnit.DAYS)
.toEpochMilli();
try (DbSession dbSession = dbClient.openSession(false)) {
return loadClosedIssues(componentUuid, dbSession);
return loadClosedIssues(dbSession, componentUuid, closeDateAfter);
}
}

private static List<DefaultIssue> loadClosedIssues(String componentUuid, DbSession dbSession) {
private static List<DefaultIssue> loadClosedIssues(DbSession dbSession, String componentUuid, long closeDateAfter) {
ClosedIssuesResultHandler handler = new ClosedIssuesResultHandler();
dbSession.getMapper(IssueMapper.class).scrollClosedByComponentUuid(componentUuid, handler);
dbSession.getMapper(IssueMapper.class).scrollClosedByComponentUuid(componentUuid, closeDateAfter, handler);
return ImmutableList.copyOf(handler.issues);
}


+ 71
- 11
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ComponentIssuesLoaderTest.java View File

@@ -19,6 +19,7 @@
*/
package org.sonar.ce.task.projectanalysis.issue;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;
@@ -39,16 +40,23 @@ import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleDefinitionDto;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.api.issue.Issue.STATUS_CLOSED;
import static org.sonar.api.utils.DateUtils.addDays;
import static org.sonar.api.utils.DateUtils.parseDateTime;

public class ComponentIssuesLoaderTest {
private static final Date NOW = parseDateTime("2018-08-17T13:44:53+0000");
private static final Date DATE_LIMIT_30_DAYS_BACK_MIDNIGHT = parseDateTime("2018-07-18T00:00:00+0000");

@Rule
public DbTester dbTester = DbTester.create(System2.INSTANCE);

private DbClient dbClient = dbTester.getDbClient();
private System2 system2 = mock(System2.class);
private ComponentIssuesLoader underTest = new ComponentIssuesLoader(dbClient,
null /* not used in loadClosedIssues */, null /* not used in loadClosedIssues */);
null /* not used in loadClosedIssues */, null /* not used in loadClosedIssues */, system2);

@Test
public void loadClosedIssues_returns_single_DefaultIssue_by_issue_based_on_first_row() {
@@ -56,11 +64,12 @@ public class ComponentIssuesLoaderTest {
ComponentDto project = dbTester.components().insertPublicProject(organization);
ComponentDto file = dbTester.components().insertComponent(ComponentTesting.newFileDto(project));
RuleDefinitionDto rule = dbTester.rules().insert(t -> t.setType(RuleType.CODE_SMELL));
IssueDto issue = dbTester.issues().insert(rule, project, file, t -> t.setStatus(STATUS_CLOSED).setIsFromHotspot(false));
Date creationDate = new Date();
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(addDays(creationDate, -5), 10));
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(creationDate, 20));
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(addDays(creationDate, -10), 30));
Date issueDate = addDays(NOW, -10);
IssueDto issue = dbTester.issues().insert(rule, project, file, t -> t.setStatus(STATUS_CLOSED).setIssueCloseDate(issueDate).setIsFromHotspot(false));
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(issueDate, 10));
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(addDays(issueDate, 3), 20));
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(addDays(issueDate, 1), 30));
when(system2.now()).thenReturn(NOW.getTime());

List<DefaultIssue> defaultIssues = underTest.loadClosedIssues(file.uuid());

@@ -74,11 +83,12 @@ public class ComponentIssuesLoaderTest {
ComponentDto project = dbTester.components().insertPublicProject(organization);
ComponentDto file = dbTester.components().insertComponent(ComponentTesting.newFileDto(project));
RuleDefinitionDto rule = dbTester.rules().insert(t -> t.setType(RuleType.CODE_SMELL));
IssueDto issue = dbTester.issues().insert(rule, project, file, t -> t.setStatus(STATUS_CLOSED).setIsFromHotspot(false));
Date creationDate = new Date();
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(addDays(creationDate, -5), 10));
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(creationDate, null));
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(addDays(creationDate, -10), 30));
Date issueDate = addDays(NOW, -10);
IssueDto issue = dbTester.issues().insert(rule, project, file, t -> t.setStatus(STATUS_CLOSED).setIssueCloseDate(issueDate).setIsFromHotspot(false));
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(issueDate, 10));
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(addDays(issueDate, 2), null));
dbTester.issues().insertFieldDiffs(issue, newToClosedDiffsWithLine(addDays(issueDate, 1), 30));
when(system2.now()).thenReturn(NOW.getTime());

List<DefaultIssue> defaultIssues = underTest.loadClosedIssues(file.uuid());

@@ -86,6 +96,56 @@ public class ComponentIssuesLoaderTest {
assertThat(defaultIssues.iterator().next().getLine()).isNull();
}

@Test
public void loadClosedIssues_returns_only_closed_issues_with_close_date() {
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto project = dbTester.components().insertPublicProject(organization);
ComponentDto file = dbTester.components().insertComponent(ComponentTesting.newFileDto(project));
RuleDefinitionDto rule = dbTester.rules().insert(t -> t.setType(RuleType.CODE_SMELL));
Date issueDate = addDays(NOW, -10);
IssueDto closedIssue = dbTester.issues().insert(rule, project, file, t -> t.setStatus(STATUS_CLOSED).setIssueCloseDate(issueDate).setIsFromHotspot(false));
dbTester.issues().insertFieldDiffs(closedIssue, newToClosedDiffsWithLine(issueDate, 10));
IssueDto issueNoCloseDate = dbTester.issues().insert(rule, project, file, t -> t.setStatus(STATUS_CLOSED).setIsFromHotspot(false));
dbTester.issues().insertFieldDiffs(issueNoCloseDate, newToClosedDiffsWithLine(issueDate, 10));
when(system2.now()).thenReturn(NOW.getTime());

List<DefaultIssue> defaultIssues = underTest.loadClosedIssues(file.uuid());

assertThat(defaultIssues)
.extracting(DefaultIssue::key)
.containsOnly(closedIssue.getKey());
}

@Test
public void loadClosedIssues_returns_only_closed_issues_which_close_date_is_from_day_30_days_ago() {
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto project = dbTester.components().insertPublicProject(organization);
ComponentDto file = dbTester.components().insertComponent(ComponentTesting.newFileDto(project));
RuleDefinitionDto rule = dbTester.rules().insert(t -> t.setType(RuleType.CODE_SMELL));
Date[] issueDates = new Date[] {
addDays(NOW, -10),
addDays(NOW, -31),
addDays(NOW, -30),
DATE_LIMIT_30_DAYS_BACK_MIDNIGHT,
addDays(NOW, -29),
addDays(NOW, -60),
};
IssueDto[] issues = Arrays.stream(issueDates)
.map(issueDate -> {
IssueDto closedIssue = dbTester.issues().insert(rule, project, file, t -> t.setStatus(STATUS_CLOSED).setIssueCloseDate(issueDate).setIsFromHotspot(false));
dbTester.issues().insertFieldDiffs(closedIssue, newToClosedDiffsWithLine(issueDate, 10));
return closedIssue;
})
.toArray(IssueDto[]::new);
when(system2.now()).thenReturn(NOW.getTime());

List<DefaultIssue> defaultIssues = underTest.loadClosedIssues(file.uuid());

assertThat(defaultIssues)
.extracting(DefaultIssue::key)
.containsOnly(issues[0].getKey(), issues[2].getKey(), issues[3].getKey(), issues[4].getKey());
}

private static FieldDiffs newToClosedDiffsWithLine(Date creationDate, @Nullable Integer oldLineValue) {
FieldDiffs fieldDiffs = new FieldDiffs().setCreationDate(addDays(creationDate, -5))
.setDiff("status", randomNonCloseStatus(), STATUS_CLOSED);

+ 2
- 2
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java View File

@@ -119,7 +119,7 @@ public class IntegrateIssuesVisitorTest {

private ArgumentCaptor<DefaultIssue> defaultIssueCaptor;

private ComponentIssuesLoader issuesLoader = new ComponentIssuesLoader(dbTester.getDbClient(), ruleRepositoryRule, activeRulesHolderRule);
private ComponentIssuesLoader issuesLoader = new ComponentIssuesLoader(dbTester.getDbClient(), ruleRepositoryRule, activeRulesHolderRule, System2.INSTANCE);
private IssueTrackingDelegator trackingDelegator;
private TrackerExecution tracker;
private ShortBranchTrackerExecution shortBranchTracker;
@@ -142,7 +142,7 @@ public class IntegrateIssuesVisitorTest {
TrackerBaseInputFactory baseInputFactory = new TrackerBaseInputFactory(issuesLoader, dbClient, movedFilesRepository);
TrackerMergeBranchInputFactory mergeInputFactory = new TrackerMergeBranchInputFactory(issuesLoader, mergeBranchComponentsUuids, dbClient);
ClosedIssuesInputFactory closedIssuesInputFactory = new ClosedIssuesInputFactory(issuesLoader, dbClient, movedFilesRepository);
tracker = new TrackerExecution(baseInputFactory, rawInputFactory, closedIssuesInputFactory, new Tracker<>(), new ComponentIssuesLoader(dbClient, ruleRepositoryRule, activeRulesHolder));
tracker = new TrackerExecution(baseInputFactory, rawInputFactory, closedIssuesInputFactory, new Tracker<>(), issuesLoader);
shortBranchTracker = new ShortBranchTrackerExecution(baseInputFactory, rawInputFactory, mergeInputFactory, new Tracker<>());
mergeBranchTracker = new MergeBranchTrackerExecution(rawInputFactory, mergeInputFactory, new Tracker<>());


+ 2
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchIssueMergerTest.java View File

@@ -32,6 +32,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.sonar.api.issue.Issue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.System2;
import org.sonar.ce.task.projectanalysis.component.ShortBranchComponentsWithIssues;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.core.issue.DefaultIssue;
@@ -94,7 +95,7 @@ public class ShortBranchIssueMergerTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
DbClient dbClient = db.getDbClient();
copier = new ShortBranchIssueMerger(new ShortBranchIssuesLoader(new ShortBranchComponentsWithIssues(treeRootHolder, dbClient), dbClient, new ComponentIssuesLoader(dbClient, null, null)), tracker,
copier = new ShortBranchIssueMerger(new ShortBranchIssuesLoader(new ShortBranchComponentsWithIssues(treeRootHolder, dbClient), dbClient, new ComponentIssuesLoader(dbClient, null, null, System2.INSTANCE)), tracker,
issueLifecycle);
projectDto = db.components().insertMainBranch(p -> p.setDbKey(PROJECT_KEY).setUuid(PROJECT_UUID));
branch1Dto = db.components().insertProjectBranch(projectDto, b -> b.setKey("myBranch1")

+ 1
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueMapper.java View File

@@ -44,7 +44,7 @@ public interface IssueMapper {

void scrollNonClosedByComponentUuid(@Param("componentUuid") String componentUuid, ResultHandler<IssueDto> handler);

void scrollClosedByComponentUuid(@Param("componentUuid") String componentUuid, ResultHandler<IssueDto> handler);
void scrollClosedByComponentUuid(@Param("componentUuid") String componentUuid, @Param("closeDateAfter") long closeDateAfter, ResultHandler<IssueDto> handler);

List<IssueDto> selectNonClosedByComponentUuidExcludingExternals(@Param("componentUuid") String componentUuid);


+ 4
- 2
server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml View File

@@ -216,7 +216,7 @@
i.issue_type &lt;&gt; 4 and (i.from_hotspot is NULL or i.from_hotspot = ${_false})
</select>

<select id="scrollClosedByComponentUuid" parameterType="String" resultType="Issue" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
<select id="scrollClosedByComponentUuid" resultType="Issue" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
select
<include refid="issueColumns"/>,
ic.change_data as closedChangeData
@@ -234,8 +234,10 @@
where
i.component_uuid = #{componentUuid,jdbcType=VARCHAR}
and i.status = 'CLOSED'
and i.issue_close_date is not null
and i.issue_close_date >= #{closeDateAfter,jdbcType=BIGINT}
and i.issue_type &lt;&gt; 4
and (i.from_hotspot is NULL or i.from_hotspot = ${_false})
and (i.from_hotspot is null or i.from_hotspot = ${_false})
order by
i.kee, ic.issue_change_creation_date desc
</select>

+ 102
- 18
server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueMapperTest.java View File

@@ -39,6 +39,7 @@ import org.sonar.api.issue.Issue;
import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.internal.AlwaysIncreasingSystem2;
import org.sonar.core.issue.FieldDiffs;
import org.sonar.core.util.UuidFactoryFast;
import org.sonar.db.DbSession;
@@ -57,6 +58,8 @@ import static org.assertj.core.api.Assertions.tuple;
@RunWith(DataProviderRunner.class)
public class IssueMapperTest {

private static final long NO_FILTERING_ON_CLOSE_DATE = 1L;

@Rule
public DbTester dbTester = DbTester.create(System2.INSTANCE);

@@ -67,6 +70,7 @@ public class IssueMapperTest {
private ComponentDto project, file, file2;
private RuleDto rule;
private Random random = new Random();
private System2 system2 = new AlwaysIncreasingSystem2();

@Before
public void setUp() throws Exception {
@@ -241,7 +245,7 @@ public class IssueMapperTest {
String componentUuid = randomAlphabetic(10);
RecorderResultHandler resultHandler = new RecorderResultHandler();

underTest.scrollClosedByComponentUuid(componentUuid, resultHandler);
underTest.scrollClosedByComponentUuid(componentUuid, new Date().getTime(), resultHandler);

assertThat(resultHandler.issues).isEmpty();
}
@@ -255,7 +259,7 @@ public class IssueMapperTest {
IssueChangeDto changeDto = insertToClosedDiff(expected);

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), resultHandler);
underTest.scrollClosedByComponentUuid(component.uuid(), NO_FILTERING_ON_CLOSE_DATE, resultHandler);

assertThat(resultHandler.issues).hasSize(1);
IssueDto issue = resultHandler.issues.iterator().next();
@@ -274,7 +278,7 @@ public class IssueMapperTest {
insertToClosedDiff(issueWithoutRule);

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), resultHandler);
underTest.scrollClosedByComponentUuid(component.uuid(), NO_FILTERING_ON_CLOSE_DATE, resultHandler);

assertThat(resultHandler.issues)
.extracting(IssueDto::getKey, t -> t.getClosedChangeData().get())
@@ -294,7 +298,7 @@ public class IssueMapperTest {
insertToClosedDiff(issueMissingProject);

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), resultHandler);
underTest.scrollClosedByComponentUuid(component.uuid(), NO_FILTERING_ON_CLOSE_DATE, resultHandler);

assertThat(resultHandler.issues)
.extracting(IssueDto::getKey, t -> t.getClosedChangeData().get())
@@ -311,7 +315,7 @@ public class IssueMapperTest {
insertNewClosedIssue(component, ruleType);

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), resultHandler);
underTest.scrollClosedByComponentUuid(component.uuid(), NO_FILTERING_ON_CLOSE_DATE, resultHandler);

assertThat(resultHandler.issues)
.extracting(IssueDto::getKey, t -> t.getClosedChangeData().get())
@@ -319,8 +323,8 @@ public class IssueMapperTest {
}

@Test
@UseDataProvider("closedIssuesSupportedRuleTypes")
public void scrollClosedByComponentUuid_does_not_return_closed_issues_of_type_SECURITY_HOTSPOT(RuleType ruleType) {
public void scrollClosedByComponentUuid_does_not_return_closed_issues_of_type_SECURITY_HOTSPOT() {
RuleType ruleType = randomSupportedRuleType();
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto component = randomComponent(organization);
IssueDto securityHotspotIssue = insertNewClosedIssue(component, RuleType.SECURITY_HOTSPOT);
@@ -329,7 +333,7 @@ public class IssueMapperTest {
IssueChangeDto issueChange = insertToClosedDiff(issue);

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), resultHandler);
underTest.scrollClosedByComponentUuid(component.uuid(), NO_FILTERING_ON_CLOSE_DATE, resultHandler);

assertThat(resultHandler.issues)
.extracting(IssueDto::getKey, t -> t.getClosedChangeData().get())
@@ -337,8 +341,8 @@ public class IssueMapperTest {
}

@Test
@UseDataProvider("closedIssuesSupportedRuleTypes")
public void scrollClosedByComponentUuid_return_closed_issues_without_isHotspot_flag(RuleType ruleType) {
public void scrollClosedByComponentUuid_returns_closed_issues_without_isHotspot_flag() {
RuleType ruleType = randomSupportedRuleType();
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto component = randomComponent(organization);
IssueDto noHotspotFlagIssue = insertNewClosedIssue(component, ruleType);
@@ -348,7 +352,7 @@ public class IssueMapperTest {
IssueChangeDto issueChange = insertToClosedDiff(issue);

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), resultHandler);
underTest.scrollClosedByComponentUuid(component.uuid(), NO_FILTERING_ON_CLOSE_DATE, resultHandler);

assertThat(resultHandler.issues)
.extracting(IssueDto::getKey, t -> t.getClosedChangeData().get())
@@ -357,6 +361,73 @@ public class IssueMapperTest {
tuple(noHotspotFlagIssue.getKey(), noFlagIssueChange.getChangeData()));
}

@Test
public void scrollClosedByComponentUuid_does_not_return_closed_issues_without_close_date() {
RuleType ruleType = randomSupportedRuleType();
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto component = randomComponent(organization);
IssueDto issueWithoutCloseDate = insertNewClosedIssue(component, ruleType, t -> t.setIssueCloseDate(null));
insertToClosedDiff(issueWithoutCloseDate);
IssueDto issueCloseDate = insertNewClosedIssue(component, ruleType);
IssueChangeDto changeDto = insertToClosedDiff(issueCloseDate);

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), NO_FILTERING_ON_CLOSE_DATE, resultHandler);

assertThat(resultHandler.issues).hasSize(1);
IssueDto issue = resultHandler.issues.iterator().next();
assertThat(issue.getKey()).isEqualTo(issue.getKey());
assertThat(issue.getClosedChangeData()).contains(changeDto.getChangeData());
}

@Test
public void scrollClosedByComponentUuid_returns_closed_issues_which_close_date_is_greater_or_equal_to_requested() {
RuleType ruleType = randomSupportedRuleType();
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto component = randomComponent(organization);
RuleDefinitionDto rule1 = dbTester.rules().insert(t -> t.setType(ruleType));
IssueDto[] issues = new IssueDto[] {
insertNewClosedIssue(component, rule1, 1_999_999L),
insertNewClosedIssue(component, rule1, 3_999_999L),
insertNewClosedIssue(component, rule1, 2_999_999L),
insertNewClosedIssue(component, rule1, 10_999_999L)
};
Arrays.stream(issues).forEach(this::insertToClosedDiff);

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), 4_000_000L, resultHandler);

assertThat(resultHandler.issues)
.extracting(IssueDto::getKey)
.containsOnly(issues[3].getKey());

resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), 11_999_999L, resultHandler);

assertThat(resultHandler.issues).isEmpty();

resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), 3_999_999L, resultHandler);

assertThat(resultHandler.issues)
.extracting(IssueDto::getKey)
.containsOnly(issues[3].getKey(), issues[1].getKey());

resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), 2_999_999L, resultHandler);

assertThat(resultHandler.issues)
.extracting(IssueDto::getKey)
.containsOnly(issues[3].getKey(), issues[1].getKey(), issues[2].getKey());

resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), 1L, resultHandler);

assertThat(resultHandler.issues)
.extracting(IssueDto::getKey)
.containsOnly(issues[3].getKey(), issues[1].getKey(), issues[2].getKey(), issues[0].getKey());
}

private void manuallySetToNullFromHotpotsColumn(IssueDto fromHostSpotIssue) {
dbTester.executeUpdateSql("update issues set from_hotspot = null where kee = '" + fromHostSpotIssue.getKey() + "'");
dbTester.commit();
@@ -373,7 +444,7 @@ public class IssueMapperTest {
IssueChangeDto issueChange = insertToClosedDiff(issue);

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), resultHandler);
underTest.scrollClosedByComponentUuid(component.uuid(), NO_FILTERING_ON_CLOSE_DATE, resultHandler);

assertThat(resultHandler.issues)
.extracting(IssueDto::getKey, t -> t.getClosedChangeData().get())
@@ -395,7 +466,7 @@ public class IssueMapperTest {
};

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), resultHandler);
underTest.scrollClosedByComponentUuid(component.uuid(), NO_FILTERING_ON_CLOSE_DATE, resultHandler);

assertThat(resultHandler.issues)
.hasSize(4)
@@ -422,7 +493,7 @@ public class IssueMapperTest {
};

RecorderResultHandler resultHandler = new RecorderResultHandler();
underTest.scrollClosedByComponentUuid(component.uuid(), resultHandler);
underTest.scrollClosedByComponentUuid(component.uuid(), NO_FILTERING_ON_CLOSE_DATE, resultHandler);

assertThat(resultHandler.issues)
.hasSize(3)
@@ -460,32 +531,45 @@ public class IssueMapperTest {
@SafeVarargs
private final IssueDto insertNewClosedIssue(ComponentDto component, RuleType ruleType, Consumer<IssueDto>... consumers) {
RuleDefinitionDto rule = dbTester.rules().insert(t -> t.setType(ruleType));
return insertNewClosedIssue(component, rule, consumers);
return insertNewClosedIssue(component, rule, system2.now(), consumers);
}

@SafeVarargs
private final IssueDto insertNewClosedIssue(ComponentDto component, RuleDefinitionDto rule, Consumer<IssueDto>... consumers) {
return insertNewClosedIssue(component, rule, system2.now(), consumers);
}

@SafeVarargs
private final IssueDto insertNewClosedIssue(ComponentDto component, RuleDefinitionDto rule, long issueCloseTime, Consumer<IssueDto>... consumers) {
IssueDto res = new IssueDto()
.setKee(UuidFactoryFast.getInstance().create())
.setRuleId(rule.getId())
.setType(rule.getType())
.setComponentUuid(component.uuid())
.setProjectUuid(component.projectUuid())
.setStatus(Issue.STATUS_CLOSED);
.setStatus(Issue.STATUS_CLOSED)
.setIssueCloseTime(issueCloseTime);
Arrays.asList(consumers).forEach(c -> c.accept(res));
underTest.insert(res);
dbSession.commit();
return res;
}

private static final RuleType[] SUPPORTED_RULE_TYPES = Arrays.stream(RuleType.values())
.filter(t -> t != RuleType.SECURITY_HOTSPOT)
.toArray(RuleType[]::new);

@DataProvider
public static Object[][] closedIssuesSupportedRuleTypes() {
return Arrays.stream(RuleType.values())
.filter(t -> t != RuleType.SECURITY_HOTSPOT)
return Arrays.stream(SUPPORTED_RULE_TYPES)
.map(t -> new Object[] {t})
.toArray(Object[][]::new);
}

private static RuleType randomSupportedRuleType() {
return SUPPORTED_RULE_TYPES[new Random().nextInt(SUPPORTED_RULE_TYPES.length)];
}

private ComponentDto randomComponent(OrganizationDto organization) {
ComponentDto project = dbTester.components().insertPublicProject(organization);
ComponentDto module = dbTester.components().insertComponent(ComponentTesting.newModuleDto(project));

Loading…
Cancel
Save