From 7d1010bbf9b85fd1b8dc08b1873781c2c67fdafd Mon Sep 17 00:00:00 2001 From: Lukasz Jarocki Date: Tue, 29 Jun 2021 11:20:50 +0200 Subject: [PATCH] SONAR-14641 added secondary sorting to all sorting when searching for issues --- .../sonar/server/issue/IssueDocTesting.java | 5 +- .../sonar/server/issue/index/IssueIndex.java | 5 ++ .../server/issue/index/IssueIndexTest.java | 54 ++++++++++++++++++- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java b/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java index d9a0325a17b..39fe01e5d7a 100644 --- a/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java +++ b/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java @@ -19,6 +19,8 @@ */ package org.sonar.server.issue; +import java.time.LocalDateTime; +import java.time.ZoneOffset; import java.util.Date; import java.util.HashMap; import org.sonar.api.resources.Scopes; @@ -50,7 +52,8 @@ public class IssueDocTesting { .setProjectUuid(mainBranchProjectUuid == null ? componentDto.projectUuid() : mainBranchProjectUuid) // File path make no sens on modules and projects .setFilePath(!componentDto.scope().equals(Scopes.PROJECT) ? componentDto.path() : null) - .setIsMainBranch(mainBranchProjectUuid == null); + .setIsMainBranch(mainBranchProjectUuid == null) + .setFuncCreationDate(Date.from(LocalDateTime.of(1970, 1, 1, 1, 1).toInstant(ZoneOffset.UTC))); } public static IssueDoc newDoc() { diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java index 9f40942a5d6..36d0663fdfa 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java @@ -320,10 +320,15 @@ public class IssueIndex { this.sorting = new Sorting(); this.sorting.add(IssueQuery.SORT_BY_STATUS, FIELD_ISSUE_STATUS); + this.sorting.add(IssueQuery.SORT_BY_STATUS, FIELD_ISSUE_KEY); this.sorting.add(IssueQuery.SORT_BY_SEVERITY, FIELD_ISSUE_SEVERITY_VALUE); + this.sorting.add(IssueQuery.SORT_BY_SEVERITY, FIELD_ISSUE_KEY); this.sorting.add(IssueQuery.SORT_BY_CREATION_DATE, FIELD_ISSUE_FUNC_CREATED_AT); + this.sorting.add(IssueQuery.SORT_BY_CREATION_DATE, FIELD_ISSUE_KEY); this.sorting.add(IssueQuery.SORT_BY_UPDATE_DATE, FIELD_ISSUE_FUNC_UPDATED_AT); + this.sorting.add(IssueQuery.SORT_BY_UPDATE_DATE, FIELD_ISSUE_KEY); this.sorting.add(IssueQuery.SORT_BY_CLOSE_DATE, FIELD_ISSUE_FUNC_CLOSED_AT); + this.sorting.add(IssueQuery.SORT_BY_CLOSE_DATE, FIELD_ISSUE_KEY); this.sorting.add(IssueQuery.SORT_BY_FILE_LINE, FIELD_ISSUE_PROJECT_UUID); this.sorting.add(IssueQuery.SORT_BY_FILE_LINE, FIELD_ISSUE_FILE_PATH); this.sorting.add(IssueQuery.SORT_BY_FILE_LINE, FIELD_ISSUE_LINE); diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java index 0c0a2c51ab7..95124161328 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java @@ -21,15 +21,18 @@ package org.sonar.server.issue.index; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterators; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; + import org.apache.lucene.search.TotalHits; import org.apache.lucene.search.TotalHits.Relation; import org.assertj.core.groups.Tuple; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.search.SearchHit; import org.junit.Rule; import org.junit.Test; @@ -124,7 +127,7 @@ public class IssueIndexTest { String key = "I" + i; issues.add(newDoc(key, file)); } - indexIssues(issues.toArray(new IssueDoc[] {})); + indexIssues(issues.toArray(new IssueDoc[]{})); IssueQuery.Builder query = IssueQuery.builder(); SearchResponse result = underTest.search(query.build(), new SearchOptions().setLimit(500)); @@ -141,7 +144,7 @@ public class IssueIndexTest { String key = "I" + i; issues.add(newDoc(key, file)); } - indexIssues(issues.toArray(new IssueDoc[] {})); + indexIssues(issues.toArray(new IssueDoc[]{})); IssueQuery.Builder query = IssueQuery.builder(); SearchResponse result = underTest.search(query.build(), new SearchOptions().setLimit(500)); @@ -150,6 +153,53 @@ public class IssueIndexTest { assertThat(result.getHits().getTotalHits().relation).isEqualTo(Relation.EQUAL_TO); } + @Test + public void search_nine_issues_with_same_creation_date_sorted_by_creation_date_order_is_sorted_also_by_key() { + ComponentDto project = newPrivateProjectDto(); + ComponentDto file = newFileDto(project, null); + List issues = new ArrayList<>(); + //we are adding issues in reverse order to see if the sort is actually doing anything + for (int i = 9; i >= 1; i--) { + String key = "I" + i; + issues.add(newDoc(key, file)); + } + indexIssues(issues.toArray(new IssueDoc[]{})); + IssueQuery.Builder query = IssueQuery.builder().asc(true); + + SearchResponse result = underTest.search(query.sort(IssueQuery.SORT_BY_CREATION_DATE).build(), new SearchOptions()); + + SearchHit[] hits = result.getHits().getHits(); + for (int i = 1; i <= 9; i++) { + assertThat(hits[i - 1].getId()).isEqualTo("I" + i); + } + } + + @Test + public void search_nine_issues_5_times_with_same_creation_date_sorted_by_creation_date_returned_issues_same_order() { + ComponentDto project = newPrivateProjectDto(); + ComponentDto file = newFileDto(project, null); + List issues = new ArrayList<>(); + //we are adding issues in reverse order to see if the sort is actually doing anything + for (int i = 9; i >= 1; i--) { + String key = "I" + i; + issues.add(newDoc(key, file)); + } + indexIssues(issues.toArray(new IssueDoc[]{})); + IssueQuery.Builder query = IssueQuery.builder().asc(true); + + SearchResponse result = underTest.search(query.sort(IssueQuery.SORT_BY_CREATION_DATE).build(), new SearchOptions()); + + SearchHit[] originalHits = result.getHits().getHits(); + for (int i = 0; i < 4; i++) { + result = underTest.search(query.sort(IssueQuery.SORT_BY_CREATION_DATE).build(), new SearchOptions()); + for (int j = 0; j < originalHits.length; j++) { + SearchHit[] hits = result.getHits().getHits(); + assertThat(originalHits[j].getId()).isEqualTo(hits[j].getId()); + } + } + + } + @Test public void authorized_issues_on_groups() { ComponentDto project1 = newPrivateProjectDto(); -- 2.39.5