From 855725871155f9524b37cc1e32cff0b25c77dab3 Mon Sep 17 00:00:00 2001 From: Dejan Milisavljevic Date: Thu, 8 Aug 2024 14:09:30 +0200 Subject: [PATCH] SONAR-22727 Define new metrics for project ratings --- .../container/ComputeEngineContainerImpl.java | 2 + .../metric/SoftwareQualitiesMetrics.java | 284 ++++++++++++++++++ .../metric/SoftwareQualitiesMetricsTest.java | 49 +++ .../platformlevel/PlatformLevel4.java | 2 + 4 files changed, 337 insertions(+) create mode 100644 server/sonar-server-common/src/main/java/org/sonar/server/metric/SoftwareQualitiesMetrics.java create mode 100644 server/sonar-server-common/src/test/java/org/sonar/server/metric/SoftwareQualitiesMetricsTest.java diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java index 4d9d5b47a8a..72a083736ed 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java @@ -109,6 +109,7 @@ import org.sonar.server.l18n.ServerI18n; import org.sonar.server.log.ServerLogging; import org.sonar.server.measure.index.ProjectMeasuresIndexer; import org.sonar.server.metric.IssueCountMetrics; +import org.sonar.server.metric.SoftwareQualitiesMetrics; import org.sonar.server.metric.UnanalyzedLanguageMetrics; import org.sonar.server.notification.DefaultNotificationManager; import org.sonar.server.notification.NotificationService; @@ -375,6 +376,7 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { // measure UnanalyzedLanguageMetrics.class, IssueCountMetrics.class, + SoftwareQualitiesMetrics.class, // components, FavoriteUpdater.class, diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/metric/SoftwareQualitiesMetrics.java b/server/sonar-server-common/src/main/java/org/sonar/server/metric/SoftwareQualitiesMetrics.java new file mode 100644 index 00000000000..b5d037ddd04 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/metric/SoftwareQualitiesMetrics.java @@ -0,0 +1,284 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.metric; + +import java.util.List; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.Metrics; + +import static org.sonar.api.measures.CoreMetrics.DOMAIN_MAINTAINABILITY; +import static org.sonar.api.measures.CoreMetrics.DOMAIN_RELIABILITY; +import static org.sonar.api.measures.CoreMetrics.DOMAIN_SECURITY; +import static org.sonar.api.measures.CoreMetrics.DOMAIN_SECURITY_REVIEW; + +public class SoftwareQualitiesMetrics implements Metrics { + + public static final String SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY = "software_quality_maintainability_rating"; + + public static final Metric SOFTWARE_QUALITY_MAINTAINABILITY_RATING = + new Metric.Builder(SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, "Software Quality Maintainability Rating", Metric.ValueType.RATING) + .setDescription("Software quality maintainability rating") + .setDomain(DOMAIN_MAINTAINABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setQualitative(true) + .setBestValue(1.0) + .setWorstValue(4.0) + .create(); + + public static final String NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY = "new_software_quality_maintainability_rating"; + + public static final Metric NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING = + new Metric.Builder(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, "Software Quality Maintainability Rating on New Code", + Metric.ValueType.RATING) + .setDescription("Software quality maintainability rating on new code") + .setDomain(DOMAIN_MAINTAINABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setDeleteHistoricalData(true) + .setOptimizedBestValue(true) + .setQualitative(true) + .setBestValue(1.0) + .setWorstValue(4.0) + .create(); + + public static final String SOFTWARE_QUALITY_RELIABILITY_RATING_KEY = "software_quality_reliability_rating"; + + public static final Metric RELIABILITY_RATING = new Metric.Builder(SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, "Software Quality Reliability Rating", Metric.ValueType.RATING) + .setDescription("Software quality reliability rating") + .setDomain(DOMAIN_RELIABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setQualitative(true) + .setBestValue(1.0) + .setWorstValue(4.0) + .create(); + + public static final String NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY = "new_software_quality_reliability_rating"; + + public static final Metric NEW_RELIABILITY_RATING = new Metric.Builder(NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, + "Software Quality Reliability Rating on New Code", Metric.ValueType.RATING) + .setDescription("Software quality reliability rating on new code") + .setDomain(DOMAIN_RELIABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setDeleteHistoricalData(true) + .setOptimizedBestValue(true) + .setQualitative(true) + .setBestValue(1.0) + .setWorstValue(4.0) + .create(); + + public static final String SOFTWARE_QUALITY_SECURITY_RATING_KEY = "software_quality_security_rating"; + + public static final Metric SOFTWARE_QUALITY_SECURITY_RATING = new Metric.Builder(SOFTWARE_QUALITY_SECURITY_RATING_KEY, + "Software Quality Security Rating", Metric.ValueType.RATING) + .setDescription("Software quality security rating") + .setDomain(DOMAIN_SECURITY) + .setDirection(Metric.DIRECTION_WORST) + .setQualitative(true) + .setBestValue(1.0) + .setWorstValue(4.0) + .create(); + + public static final String NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY = "new_software_quality_security_rating"; + + public static final Metric NEW_SOFTWARE_QUALITY_SECURITY_RATING = new Metric.Builder(NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, + "Software Quality Security Rating on New Code", Metric.ValueType.RATING) + .setDescription("Software quality security rating on new code") + .setDomain(DOMAIN_SECURITY) + .setDirection(Metric.DIRECTION_WORST) + .setDeleteHistoricalData(true) + .setOptimizedBestValue(true) + .setQualitative(true) + .setBestValue(1.0) + .setWorstValue(4.0) + .create(); + + public static final String SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY = "software_quality_security_review_rating"; + + public static final Metric SOFTWARE_QUALITY_SECURITY_REVIEW_RATING = + new Metric.Builder(SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, "Software Quality Security Review Rating", Metric.ValueType.RATING) + .setDescription("Software quality security review rating") + .setDomain(DOMAIN_SECURITY_REVIEW) + .setDirection(Metric.DIRECTION_WORST) + .setQualitative(true) + .setBestValue(1.0) + .setWorstValue(4.0) + .create(); + + public static final String NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY = "new_software_quality_security_review_rating"; + + public static final Metric NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING = + new Metric.Builder(NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, "Software Quality Security Review Rating on New Code", + Metric.ValueType.RATING) + .setDescription("Software quality security review rating on new code") + .setDomain(DOMAIN_SECURITY_REVIEW) + .setDirection(Metric.DIRECTION_WORST) + .setDeleteHistoricalData(true) + .setOptimizedBestValue(true) + .setQualitative(true) + .setBestValue(1.0) + .setWorstValue(4.0) + .create(); + + public static final String EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A_KEY = + "effort_to_reach_software_quality_maintainability_rating_a"; + + public static final Metric EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A = + new Metric.Builder(EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A_KEY, + "Software Quality Effort to Reach Maintainability Rating A", Metric.ValueType.WORK_DUR) + .setDescription("Software quality effort to reach maintainability rating A") + .setDomain(DOMAIN_MAINTAINABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setQualitative(true) + .setBestValue(0.0) + .setOptimizedBestValue(true) + .create(); + + public static final String SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY = + "software_quality_maintainability_remediation_effort"; + + public static final Metric SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT = + new Metric.Builder(SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, "Software Quality Maintainability Remediation Effort", + Metric.ValueType.WORK_DUR) + .setDescription("Software quality total effort (in minutes) to fix all the maintainability issues on the component and therefore to comply to all the requirements.") + .setDomain(DOMAIN_MAINTAINABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setOptimizedBestValue(true) + .setBestValue(0.0) + .setQualitative(true) + .create(); + + public static final String NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY = + "new_software_quality_maintainability_remediation_effort"; + + public static final Metric NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT = + new Metric.Builder(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, "Software Quality Maintainability Remediation Effort on new code", + Metric.ValueType.WORK_DUR) + .setDescription("Software quality total effort (in minutes) to fix all the maintainability issues on new code on the component and therefore to comply to all the requirements.") + .setDomain(DOMAIN_MAINTAINABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setOptimizedBestValue(true) + .setBestValue(0.0) + .setQualitative(true) + .setDeleteHistoricalData(true) + .create(); + + + public static final String SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY = "software_quality_security_remediation_effort"; + + public static final Metric SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT = + new Metric.Builder(SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, "Software Quality Security Remediation Effort", + Metric.ValueType.WORK_DUR) + .setDescription("Software quality security remediation effort") + .setDomain(DOMAIN_SECURITY) + .setDirection(Metric.DIRECTION_WORST) + .setOptimizedBestValue(true) + .setBestValue(0.0) + .setQualitative(true) + .create(); + + public static final String NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY = "new_software_quality_security_remediation_effort"; + + public static final Metric NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT = + new Metric.Builder(NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, "Software Quality Security Remediation Effort on New Code", + Metric.ValueType.WORK_DUR) + .setDescription("Software quality security remediation effort on new code") + .setDomain(DOMAIN_SECURITY) + .setDirection(Metric.DIRECTION_WORST) + .setOptimizedBestValue(true) + .setBestValue(0.0) + .setQualitative(true) + .setDeleteHistoricalData(true) + .create(); + + public static final String SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY = "software_quality_reliability_remediation_effort"; + + public static final Metric RELIABILITY_REMEDIATION_EFFORT = + new Metric.Builder(SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, "Software Quality Reliability Remediation Effort", + Metric.ValueType.WORK_DUR) + .setDescription("Software quality reliability remediation effort") + .setDomain(DOMAIN_RELIABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setOptimizedBestValue(true) + .setBestValue(0.0) + .setQualitative(true) + .create(); + + public static final String NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY = + "new_software_quality_reliability_remediation_effort"; + + public static final Metric NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT = + new Metric.Builder(NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, "Software Quality Reliability Remediation Effort on New Code", + Metric.ValueType.WORK_DUR) + .setDescription("Software quality reliability remediation effort on new code") + .setDomain(DOMAIN_RELIABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setOptimizedBestValue(true) + .setBestValue(0.0) + .setQualitative(true) + .setDeleteHistoricalData(true) + .create(); + + public static final String SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO_KEY = "software_quality_maintainability_debt_ratio"; + + public static final Metric SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO = + new Metric.Builder(SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO_KEY, "Software Quality Technical Debt Ratio", Metric.ValueType.PERCENT) + .setDescription("Software quality ratio of the actual technical debt compared to the estimated cost to develop the whole source code from scratch") + .setDomain(DOMAIN_MAINTAINABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setOptimizedBestValue(true) + .setBestValue(0.0) + .setQualitative(true) + .create(); + + public static final String NEW_SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO_KEY = "new_software_quality_maintainability_debt_ratio"; + + public static final Metric NEW_SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO = + new Metric.Builder(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO_KEY, "Software Quality Technical Debt Ratio on New Code", + Metric.ValueType.PERCENT) + .setDescription("Software quality technical debt ratio software quality of new/changed code.") + .setDomain(DOMAIN_MAINTAINABILITY) + .setDirection(Metric.DIRECTION_WORST) + .setOptimizedBestValue(true) + .setBestValue(0.0) + .setQualitative(true) + .create(); + + @Override + public List getMetrics() { + return List.of( + SOFTWARE_QUALITY_MAINTAINABILITY_RATING, + NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING, + RELIABILITY_RATING, + NEW_RELIABILITY_RATING, + SOFTWARE_QUALITY_SECURITY_RATING, + NEW_SOFTWARE_QUALITY_SECURITY_RATING, + SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, + NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, + EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A, + SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, + NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, + SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT, + NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT, + RELIABILITY_REMEDIATION_EFFORT, + NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT, + SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO, + NEW_SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO + ); + } +} diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/metric/SoftwareQualitiesMetricsTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/metric/SoftwareQualitiesMetricsTest.java new file mode 100644 index 00000000000..717c88af58a --- /dev/null +++ b/server/sonar-server-common/src/test/java/org/sonar/server/metric/SoftwareQualitiesMetricsTest.java @@ -0,0 +1,49 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.metric; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class SoftwareQualitiesMetricsTest { + @Test + void getMetrics() { + assertThat(new SoftwareQualitiesMetrics().getMetrics()) + .containsExactlyInAnyOrder( + SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING, + SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING, + SoftwareQualitiesMetrics.RELIABILITY_RATING, + SoftwareQualitiesMetrics.NEW_RELIABILITY_RATING, + SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING, + SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING, + SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, + SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, + SoftwareQualitiesMetrics.EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A, + SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, + SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, + SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT, + SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT, + SoftwareQualitiesMetrics.RELIABILITY_REMEDIATION_EFFORT, + SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT, + SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO, + SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO); + } +} diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index 2aa955e21e6..f6d3eef8ccd 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -159,6 +159,7 @@ import org.sonar.server.measure.index.ProjectsEsModule; import org.sonar.server.measure.live.LiveMeasureModule; import org.sonar.server.measure.ws.MeasuresWsModule; import org.sonar.server.metric.IssueCountMetrics; +import org.sonar.server.metric.SoftwareQualitiesMetrics; import org.sonar.server.metric.UnanalyzedLanguageMetrics; import org.sonar.server.metric.ws.MetricsWsModule; import org.sonar.server.monitoring.ComputeEngineMetricStatusTask; @@ -394,6 +395,7 @@ public class PlatformLevel4 extends PlatformLevel { new MeasuresWsModule(), UnanalyzedLanguageMetrics.class, IssueCountMetrics.class, + SoftwareQualitiesMetrics.class, new QualityGateModule(), new QualityGateWsModule(), -- 2.39.5