aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-dao
diff options
context:
space:
mode:
authorEric Giffon <eric.giffon@sonarsource.com>2024-01-24 16:11:02 +0100
committersonartech <sonartech@sonarsource.com>2024-01-31 20:03:36 +0000
commitad8e3304ea05510914b268ce24875c59436c46e1 (patch)
tree2271291f09116a1e110e8ade15eb0185ffb28ace /server/sonar-db-dao
parent6381e5a67c6363e66d1ef7b4d6d5ed6919894d87 (diff)
downloadsonarqube-ad8e3304ea05510914b268ce24875c59436c46e1.tar.gz
sonarqube-ad8e3304ea05510914b268ce24875c59436c46e1.zip
SONAR-21455 Compute high_impact_accepted_issues with impacts query
Diffstat (limited to 'server/sonar-db-dao')
-rw-r--r--server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java75
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueGroupDto.java10
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueImpactGroupDto.java21
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml31
4 files changed, 69 insertions, 68 deletions
diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java
index f32cd93dca0..4ae47c90d5c 100644
--- a/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java
+++ b/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java
@@ -466,22 +466,17 @@ public class IssueDaoIT {
ComponentDto file = db.components().insertComponent(ComponentTesting.newFileDto(project));
RuleDto rule = db.rules().insert();
db.issues().insert(rule, project, file,
- i -> i.setStatus("RESOLVED").setResolution("FALSE-POSITIVE").setSeverity("MAJOR").setType(RuleType.BUG).setIssueCreationTime(1_500L)
- .replaceAllImpacts(List.of(createImpact(SECURITY, HIGH), createImpact(MAINTAINABILITY, LOW))));
+ i -> i.setStatus("RESOLVED").setResolution("FALSE-POSITIVE").setSeverity("MAJOR").setType(RuleType.BUG).setIssueCreationTime(1_500L));
db.issues().insert(rule, project, file,
- i -> i.setStatus("OPEN").setResolution(null).setSeverity("CRITICAL").setType(RuleType.BUG).setIssueCreationTime(1_600L)
- .replaceAllImpacts(List.of(createImpact(SECURITY, HIGH), createImpact(MAINTAINABILITY, HIGH))));
+ i -> i.setStatus("OPEN").setResolution(null).setSeverity("CRITICAL").setType(RuleType.BUG).setIssueCreationTime(1_600L));
IssueDto criticalBug2 = db.issues().insert(rule, project, file,
- i -> i.setStatus("OPEN").setResolution(null).setSeverity("CRITICAL").setType(RuleType.BUG).setIssueCreationTime(1_700L)
- .replaceAllImpacts(List.of(createImpact(SECURITY, MEDIUM), createImpact(MAINTAINABILITY, LOW))));
+ i -> i.setStatus("OPEN").setResolution(null).setSeverity("CRITICAL").setType(RuleType.BUG).setIssueCreationTime(1_700L));
// closed issues are ignored
db.issues().insert(rule, project, file,
- i -> i.setStatus("CLOSED").setResolution("REMOVED").setSeverity("CRITICAL").setType(RuleType.BUG).setIssueCreationTime(1_700L)
- .replaceAllImpacts(List.of(createImpact(SECURITY, HIGH))));
+ i -> i.setStatus("CLOSED").setResolution("REMOVED").setSeverity("CRITICAL").setType(RuleType.BUG).setIssueCreationTime(1_700L));
Collection<IssueGroupDto> result = underTest.selectIssueGroupsByComponent(db.getSession(), file, 1_000L);
- assertThat(result).hasSize(3);
assertThat(result.stream().mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
assertThat(result.stream().filter(g -> g.getRuleType() == RuleType.BUG.getDbConstant()).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
@@ -491,7 +486,6 @@ public class IssueDaoIT {
assertThat(result.stream().filter(g -> g.getSeverity().equals("CRITICAL")).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(2);
assertThat(result.stream().filter(g -> g.getSeverity().equals("MAJOR")).mapToLong(IssueGroupDto::getCount).sum()).isOne();
assertThat(result.stream().filter(g -> g.getSeverity().equals("MINOR")).mapToLong(IssueGroupDto::getCount).sum()).isZero();
- assertThat(result.stream().filter(IssueGroupDto::hasHighImpactSeverity).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(2);
assertThat(result.stream().filter(g -> g.getStatus().equals("OPEN")).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(2);
assertThat(result.stream().filter(g -> g.getStatus().equals("RESOLVED")).mapToLong(IssueGroupDto::getCount).sum()).isOne();
@@ -514,11 +508,6 @@ public class IssueDaoIT {
assertThat(result.stream().filter(g -> !g.isInLeak()).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
}
- @NotNull
- private static ImpactDto createImpact(SoftwareQuality softwareQuality, Severity high) {
- return new ImpactDto().setUuid(UuidFactoryFast.getInstance().create()).setSoftwareQuality(softwareQuality).setSeverity(high);
- }
-
@Test
public void selectGroupsOfComponentTreeOnLeak_on_file_new_code_reference_branch() {
ComponentDto project = db.components().insertPublicProject().getMainBranchComponent();
@@ -526,8 +515,6 @@ public class IssueDaoIT {
RuleDto rule = db.rules().insert();
IssueDto fpBug = db.issues().insert(rule, project, file,
i -> i.setStatus("RESOLVED").setResolution("FALSE-POSITIVE").setSeverity("MAJOR").setType(RuleType.BUG));
- IssueDto acceptedBug = db.issues().insert(rule, project, file,
- i -> i.setStatus("RESOLVED").setResolution("WONTFIX").setSeverity("MAJOR").setType(RuleType.BUG));
IssueDto criticalBug1 = db.issues().insert(rule, project, file,
i -> i.setStatus("OPEN").setResolution(null).setSeverity("CRITICAL").setType(RuleType.BUG));
IssueDto criticalBug2 = db.issues().insert(rule, project, file,
@@ -538,31 +525,29 @@ public class IssueDaoIT {
// two issues part of new code period on reference branch
db.issues().insertNewCodeReferenceIssue(fpBug);
- db.issues().insertNewCodeReferenceIssue(acceptedBug);
db.issues().insertNewCodeReferenceIssue(criticalBug1);
db.issues().insertNewCodeReferenceIssue(criticalBug2);
Collection<IssueGroupDto> result = underTest.selectIssueGroupsByComponent(db.getSession(), file, -1);
- assertThat(result.stream().mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(5);
+ assertThat(result.stream().mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(4);
- assertThat(result.stream().filter(g -> g.getRuleType() == RuleType.BUG.getDbConstant()).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(5);
+ assertThat(result.stream().filter(g -> g.getRuleType() == RuleType.BUG.getDbConstant()).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(4);
assertThat(result.stream().filter(g -> g.getRuleType() == RuleType.CODE_SMELL.getDbConstant()).mapToLong(IssueGroupDto::getCount).sum()).isZero();
assertThat(result.stream().filter(g -> g.getRuleType() == RuleType.VULNERABILITY.getDbConstant()).mapToLong(IssueGroupDto::getCount).sum()).isZero();
assertThat(result.stream().filter(g -> g.getSeverity().equals("CRITICAL")).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
- assertThat(result.stream().filter(g -> g.getSeverity().equals("MAJOR")).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(2);
+ assertThat(result.stream().filter(g -> g.getSeverity().equals("MAJOR")).mapToLong(IssueGroupDto::getCount).sum()).isOne();
assertThat(result.stream().filter(g -> g.getSeverity().equals("MINOR")).mapToLong(IssueGroupDto::getCount).sum()).isZero();
assertThat(result.stream().filter(g -> g.getStatus().equals("OPEN")).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
- assertThat(result.stream().filter(g -> g.getStatus().equals("RESOLVED")).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(2);
+ assertThat(result.stream().filter(g -> g.getStatus().equals("RESOLVED")).mapToLong(IssueGroupDto::getCount).sum()).isOne();
assertThat(result.stream().filter(g -> g.getStatus().equals("CLOSED")).mapToLong(IssueGroupDto::getCount).sum()).isZero();
assertThat(result.stream().filter(g -> "FALSE-POSITIVE".equals(g.getResolution())).mapToLong(IssueGroupDto::getCount).sum()).isOne();
- assertThat(result.stream().filter(g -> "WONTFIX".equals(g.getResolution())).mapToLong(IssueGroupDto::getCount).sum()).isOne();
assertThat(result.stream().filter(g -> g.getResolution() == null).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
- assertThat(result.stream().filter(IssueGroupDto::isInLeak).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(4);
+ assertThat(result.stream().filter(IssueGroupDto::isInLeak).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
assertThat(result.stream().filter(g -> !g.isInLeak()).mapToLong(IssueGroupDto::getCount).sum()).isOne();
}
@@ -572,26 +557,46 @@ public class IssueDaoIT {
ComponentDto file = db.components().insertComponent(ComponentTesting.newFileDto(project));
RuleDto rule = db.rules().insert();
db.issues().insert(rule, project, file,
- i -> i.replaceAllImpacts(List.of(createImpact(SECURITY, HIGH), createImpact(MAINTAINABILITY, LOW))));
+ i -> i.setStatus(STATUS_OPEN).replaceAllImpacts(List.of(createImpact(SECURITY, HIGH), createImpact(MAINTAINABILITY, LOW))));
db.issues().insert(rule, project, file,
- i -> i.replaceAllImpacts(List.of(createImpact(SECURITY, HIGH), createImpact(MAINTAINABILITY, HIGH))));
+ i -> i.setStatus(STATUS_OPEN).replaceAllImpacts(List.of(createImpact(SECURITY, HIGH), createImpact(MAINTAINABILITY, HIGH))));
db.issues().insert(rule, project, file,
- i -> i.replaceAllImpacts(List.of(createImpact(SECURITY, HIGH))));
- // closed issues are ignored
+ i -> i.setStatus(STATUS_REOPENED).replaceAllImpacts(List.of(createImpact(SECURITY, HIGH))));
+ db.issues().insert(rule, project, file,
+ i -> i.setStatus(STATUS_RESOLVED).setResolution(RESOLUTION_WONT_FIX).replaceAllImpacts(List.of(createImpact(SECURITY, HIGH))));
+ // issues in ignored status
db.issues().insert(rule, project, file,
i -> i.setStatus(Issue.STATUS_CLOSED).replaceAllImpacts(List.of(createImpact(SECURITY, HIGH))));
+ db.issues().insert(rule, project, file,
+ i -> i.setStatus(STATUS_RESOLVED).setResolution(RESOLUTION_FALSE_POSITIVE).replaceAllImpacts(List.of(createImpact(SECURITY, HIGH))));
Collection<IssueImpactGroupDto> result = underTest.selectIssueImpactGroupsByComponent(db.getSession(), file);
- assertThat(result).hasSize(3);
- assertThat(result.stream().mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(5);
+ assertThat(result).hasSize(5);
+ assertThat(result.stream().mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(6);
+
+ assertThat(result.stream().filter(g -> g.getSoftwareQuality() == SECURITY).mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(4);
+ assertThat(result.stream().filter(g -> g.getSoftwareQuality() == MAINTAINABILITY).mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(2);
+
+ assertThat(result.stream().filter(g -> g.getSeverity() == HIGH).mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(5);
+ assertThat(result.stream().filter(g -> g.getSeverity() == LOW).mapToLong(IssueImpactGroupDto::getCount).sum()).isOne();
+
+ assertThat(result.stream().filter(g -> STATUS_OPEN.equals(g.getStatus())).mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(4);
+ assertThat(result.stream().filter(g -> STATUS_REOPENED.equals(g.getStatus())).mapToLong(IssueImpactGroupDto::getCount).sum()).isOne();
+ assertThat(result.stream().filter(g -> STATUS_RESOLVED.equals(g.getStatus())).mapToLong(IssueImpactGroupDto::getCount).sum()).isOne();
+
+ assertThat(result.stream().filter(g -> RESOLUTION_WONT_FIX.equals(g.getResolution())).mapToLong(IssueImpactGroupDto::getCount).sum()).isOne();
+ assertThat(result.stream().filter(g -> g.getResolution() == null).mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(5);
- assertThat(result.stream().filter(g -> MAINTAINABILITY == g.getSoftwareQuality()).mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(2);
- assertThat(result.stream().filter(g -> SECURITY == g.getSoftwareQuality()).mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(3);
- assertThat(result.stream().filter(g -> SECURITY == g.getSoftwareQuality() && HIGH == g.getSeverity()).mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(3);
- assertThat(result.stream().filter(g -> HIGH == g.getSeverity()).mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(4);
- assertThat(result.stream().filter(g -> LOW == g.getSeverity()).mapToLong(IssueImpactGroupDto::getCount).sum()).isEqualTo(1);
+ assertThat(result.stream().noneMatch(g -> STATUS_CLOSED.equals(g.getResolution()))).isTrue();
+ assertThat(result.stream().noneMatch(g -> RESOLUTION_FALSE_POSITIVE.equals(g.getResolution()))).isTrue();
assertThat(result.stream().noneMatch(g -> RELIABILITY == g.getSoftwareQuality())).isTrue();
+ assertThat(result.stream().noneMatch(g -> MEDIUM == g.getSeverity())).isTrue();
+ }
+
+ @NotNull
+ private static ImpactDto createImpact(SoftwareQuality softwareQuality, Severity high) {
+ return new ImpactDto().setUuid(UuidFactoryFast.getInstance().create()).setSoftwareQuality(softwareQuality).setSeverity(high);
}
@Test
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueGroupDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueGroupDto.java
index 618a33187ff..735711d2983 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueGroupDto.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueGroupDto.java
@@ -25,7 +25,6 @@ import javax.annotation.Nullable;
public class IssueGroupDto {
private int ruleType;
private String severity;
- private boolean hasHighImpactSeverity;
@Nullable
private String resolution;
private String status;
@@ -45,10 +44,6 @@ public class IssueGroupDto {
return severity;
}
- public boolean hasHighImpactSeverity() {
- return hasHighImpactSeverity;
- }
-
@CheckForNull
public String getResolution() {
return resolution;
@@ -80,11 +75,6 @@ public class IssueGroupDto {
return this;
}
- public IssueGroupDto setHasHighImpactSeverity(boolean hasHighImpactSeverity) {
- this.hasHighImpactSeverity = hasHighImpactSeverity;
- return this;
- }
-
public IssueGroupDto setResolution(@Nullable String resolution) {
this.resolution = resolution;
return this;
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueImpactGroupDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueImpactGroupDto.java
index 28e8a8451c6..9455e3a66ec 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueImpactGroupDto.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueImpactGroupDto.java
@@ -19,11 +19,15 @@
*/
package org.sonar.db.issue;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import org.sonar.api.issue.impact.Severity;
import org.sonar.api.issue.impact.SoftwareQuality;
public class IssueImpactGroupDto {
+ private String status;
+ private String resolution;
private SoftwareQuality softwareQuality;
private Severity severity;
private long count;
@@ -32,6 +36,23 @@ public class IssueImpactGroupDto {
// nothing to do
}
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ @CheckForNull
+ public String getResolution() {
+ return resolution;
+ }
+
+ public void setResolution(@Nullable String resolution) {
+ this.resolution = resolution;
+ }
+
public SoftwareQuality getSoftwareQuality() {
return softwareQuality;
}
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml
index ae88f48bff8..31f459370f3 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml
@@ -458,11 +458,9 @@
</select>
<select id="selectIssueGroupsByComponent" resultType="org.sonar.db.issue.IssueGroupDto" parameterType="map">
- <include refid="withHighImpactSeverityIssues"/>
select
i.issue_type as ruleType,
i.severity as severity,
- exists(select 1 from high_impact_severity_issues hisi where hisi.kee = i.kee) as hasHighImpactSeverity,
i.resolution as resolution,
i.status as status, sum(i.effort) as effort,
count(i.issue_type) as "count",
@@ -478,20 +476,9 @@
</if>
where i.status &lt;&gt; 'CLOSED'
and i.component_uuid = #{component.uuid,jdbcType=VARCHAR}
- group by i.issue_type, i.severity, hasHighImpactSeverity, i.resolution, i.status, inLeak
+ group by i.issue_type, i.severity, i.resolution, i.status, inLeak
</select>
- <sql id="withHighImpactSeverityIssues">
- with high_impact_severity_issues as (
- select distinct kee
- from issues i
- inner join issues_impacts ii on ii.issue_key = i.kee
- where i.status &lt;&gt; 'CLOSED'
- and i.component_uuid = #{component.uuid,jdbcType=VARCHAR}
- and ii.severity = 'HIGH'
- )
- </sql>
-
<select id="selectIssueGroupsByComponent" resultType="org.sonar.db.issue.IssueGroupDto" parameterType="map" databaseId="oracle">
<include refid="selectIssueGroupsByComponentVendorSpecific"/>
</select>
@@ -501,11 +488,9 @@
</select>
<sql id="selectIssueGroupsByComponentVendorSpecific">
- <include refid="withHighImpactSeverityIssues"/>
select
i2.issue_type as ruleType,
i2.severity as severity,
- i2.hasHighImpactSeverity as hasHighImpactSeverity,
i2.resolution as resolution,
i2.status as status,
sum(i2.effort) as effort,
@@ -515,7 +500,6 @@
select
i.issue_type,
i.severity,
- case when exists(select 1 from high_impact_severity_issues hisi where hisi.kee = i.kee) then 1 else 0 end as hasHighImpactSeverity,
i.resolution,
i.status,
i.effort,
@@ -532,21 +516,22 @@
where i.status &lt;&gt; 'CLOSED'
and i.component_uuid = #{component.uuid,jdbcType=VARCHAR}
) i2
- group by i2.issue_type, i2.severity, i2.hasHighImpactSeverity, i2.resolution, i2.status, i2.inLeak
+ group by i2.issue_type, i2.severity, i2.resolution, i2.status, i2.inLeak
</sql>
<select id="selectIssueImpactGroupsByComponent" resultType="org.sonar.db.issue.IssueImpactGroupDto" parameterType="map">
select
+ i.status as status,
+ i.resolution as resolution,
ii.software_quality as softwareQuality,
ii.severity as severity,
count(i.kee) as "count"
from issues i
- left join issues_impacts ii on i.kee = ii.issue_key
- where 1=1
- and i.status in ('OPEN', 'REOPENED', 'CONFIRMED')
- and i.issue_type != 4
+ inner join issues_impacts ii on i.kee = ii.issue_key
+ where i.status &lt;&gt; 'CLOSED'
+ and (i.resolution is null or i.resolution = 'WONTFIX')
and i.component_uuid = #{component.uuid,jdbcType=VARCHAR}
- group by ii.software_quality, ii.severity
+ group by i.status, i.resolution, ii.software_quality, ii.severity
</select>
<select id="selectIssueKeysByComponentUuid" parameterType="string" resultType="string">