aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server-common
diff options
context:
space:
mode:
authorNolwenn Cadic <98824442+Nolwenn-cadic-sonarsource@users.noreply.github.com>2023-10-26 14:30:36 +0200
committersonartech <sonartech@sonarsource.com>2023-10-26 20:02:58 +0000
commit2eaf4da9b14cc5bfa73719b660c5db706672d182 (patch)
tree0070c5710f6f0c90f5aa333bc373c1a5d29c81a3 /server/sonar-server-common
parentc49df4a6f7ee55283c891139d79418a482538769 (diff)
downloadsonarqube-2eaf4da9b14cc5bfa73719b660c5db706672d182.tar.gz
sonarqube-2eaf4da9b14cc5bfa73719b660c5db706672d182.zip
SONAR-20787 Add telemetry about quality gate conditions and sonar way (#9743)
Diffstat (limited to 'server/sonar-server-common')
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGate.java2
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java8
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryData.java16
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java11
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ConditionTest.java2
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java92
6 files changed, 112 insertions, 19 deletions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGate.java b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGate.java
index c03a0d8f6e6..d4082e0288c 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGate.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGate.java
@@ -28,6 +28,8 @@ import static java.util.Objects.requireNonNull;
@Immutable
public class QualityGate {
+
+ public static final String BUILTIN_QUALITY_GATE_NAME = "Sonar way";
private final String id;
private final String name;
private final Set<Condition> conditions;
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java
index 32dad6ce43c..1bc482d9145 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java
@@ -25,6 +25,9 @@ import org.sonar.db.DbSession;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.qualitygate.QualityGateDto;
+import static java.lang.String.format;
+import static org.sonar.server.qualitygate.QualityGate.BUILTIN_QUALITY_GATE_NAME;
+
public class QualityGateFinder {
private final DbClient dbClient;
@@ -55,6 +58,11 @@ public class QualityGateFinder {
return Optional.ofNullable(dbClient.qualityGateDao().selectDefault(dbSession)).orElseThrow(() -> new IllegalStateException("Default quality gate is missing"));
}
+ public QualityGateDto getSonarWay(DbSession dbSession) {
+ return Optional.ofNullable(dbClient.qualityGateDao().selectByName(dbSession, BUILTIN_QUALITY_GATE_NAME)).orElseThrow(() ->
+ new IllegalStateException(format("%s quality gate is missing", BUILTIN_QUALITY_GATE_NAME)));
+ }
+
public static class QualityGateData {
private final String uuid;
private final String name;
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryData.java b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryData.java
index 6ec247b38b7..18e545d6ae5 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryData.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryData.java
@@ -31,6 +31,7 @@ import org.sonar.core.platform.EditionProvider;
import org.sonar.core.platform.EditionProvider.Edition;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.user.UserTelemetryDto;
+import org.sonar.server.qualitygate.Condition;
import static java.util.Objects.requireNonNullElse;
import static org.sonar.db.newcodeperiod.NewCodePeriodType.PREVIOUS_VERSION;
@@ -43,6 +44,7 @@ public class TelemetryData {
private final Database database;
private final EditionProvider.Edition edition;
private final String defaultQualityGate;
+ private final String sonarWayQualityGate;
private final Long installationDate;
private final String installationVersion;
private final boolean inContainer;
@@ -68,6 +70,7 @@ public class TelemetryData {
database = builder.database;
edition = builder.edition;
defaultQualityGate = builder.defaultQualityGate;
+ sonarWayQualityGate = builder.sonarWayQualityGate;
installationDate = builder.installationDate;
installationVersion = builder.installationVersion;
inContainer = builder.inContainer;
@@ -114,6 +117,10 @@ public class TelemetryData {
return defaultQualityGate;
}
+ public String getSonarWayQualityGate() {
+ return sonarWayQualityGate;
+ }
+
public Long getInstallationDate() {
return installationDate;
}
@@ -190,6 +197,8 @@ public class TelemetryData {
private Database database;
private Edition edition;
private String defaultQualityGate;
+
+ private String sonarWayQualityGate;
private Long installationDate;
private String installationVersion;
private boolean inContainer = false;
@@ -246,6 +255,11 @@ public class TelemetryData {
return this;
}
+ Builder setSonarWayQualityGate(String sonarWayQualityGate) {
+ this.sonarWayQualityGate = sonarWayQualityGate;
+ return this;
+ }
+
Builder setInstallationDate(@Nullable Long installationDate) {
this.installationDate = installationDate;
return this;
@@ -360,7 +374,7 @@ public class TelemetryData {
record Project(String projectUuid, Long lastAnalysis, String language, String qualityProfile, Long loc) {
}
- record QualityGate(String uuid, String caycStatus) {
+ record QualityGate(String uuid, String caycStatus, List<Condition> conditions) {
}
public record QualityProfile(String uuid, @Nullable String parentUuid, String language, boolean isDefault,
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java
index 94315180324..b3148e9ddb3 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java
@@ -63,6 +63,7 @@ public class TelemetryDataJsonWriter {
json.prop(NCD_ID, telemetryData.getNcdId());
telemetryData.getEdition().ifPresent(e -> json.prop("edition", e.name().toLowerCase(Locale.ENGLISH)));
json.prop("defaultQualityGate", telemetryData.getDefaultQualityGate());
+ json.prop("sonarway_quality_gate_uuid", telemetryData.getSonarWayQualityGate());
json.name("database");
json.beginObject();
json.prop("name", telemetryData.getDatabase().name());
@@ -222,6 +223,16 @@ public class TelemetryDataJsonWriter {
json.beginObject();
json.prop("uuid", qualityGate.uuid());
json.prop("caycStatus", qualityGate.caycStatus());
+ json.name("conditions");
+ json.beginArray();
+ qualityGate.conditions().forEach(condition -> {
+ json.beginObject();
+ json.prop("metric", condition.getMetricKey());
+ json.prop("comparison_operator", condition.getOperator().getDbValue());
+ json.prop("error_value", condition.getErrorThreshold());
+ json.endObject();
+ });
+ json.endArray();
json.endObject();
});
json.endArray();
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ConditionTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ConditionTest.java
index f3f24f7a822..947a8e29537 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ConditionTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ConditionTest.java
@@ -40,7 +40,7 @@ public class ConditionTest {
}
@Test
- public void constructor_throws_NPE_if_operator_is_null() {
+ public void constructor_throws_NPE_if_operator_operator_is_null() {
assertThatThrownBy(() -> new Condition(METRIC_KEY, null, ERROR_THRESHOLD))
.isInstanceOf(NullPointerException.class)
.hasMessage("operator can't be null");
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java
index bc98e99ad77..b523f5b0d4a 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java
@@ -42,6 +42,7 @@ import org.sonar.core.platform.EditionProvider;
import org.sonar.core.telemetry.TelemetryExtension;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.user.UserTelemetryDto;
+import org.sonar.server.qualitygate.Condition;
import static java.util.stream.Collectors.joining;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
@@ -50,6 +51,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.db.newcodeperiod.NewCodePeriodType.NUMBER_OF_DAYS;
import static org.sonar.db.newcodeperiod.NewCodePeriodType.PREVIOUS_VERSION;
+import static org.sonar.server.qualitygate.Condition.Operator.fromDbValue;
import static org.sonar.test.JsonAssert.assertJson;
@RunWith(DataProviderRunner.class)
@@ -121,6 +123,20 @@ public class TelemetryDataJsonWriterTest {
}
@Test
+ public void writes_sonarWay_qg() {
+ TelemetryData data = telemetryBuilder()
+ .setSonarWayQualityGate("sonarWayUUID")
+ .build();
+
+ String json = writeTelemetryData(data);
+ assertJson(json).isSimilarTo("""
+ {
+ "sonarway_quality_gate_uuid": "%s"
+ }
+ """.formatted(data.getSonarWayQualityGate()));
+ }
+
+ @Test
public void writes_database() {
String name = randomAlphabetic(12);
String version = randomAlphabetic(10);
@@ -517,20 +533,56 @@ public class TelemetryDataJsonWriterTest {
assertJson(json).isSimilarTo("""
{
"quality-gates": [
- {
- "uuid": "uuid-0",
- "caycStatus": "non-compliant"
- },
- {
- "uuid": "uuid-1",
- "caycStatus": "compliant"
- },
- {
- "uuid": "uuid-2",
- "caycStatus": "over-compliant"
- }
- ]
- }
+ {
+ "uuid": "uuid-0",
+ "caycStatus": "non-compliant",
+ "conditions": [
+ {
+ "metric": "new_coverage",
+ "comparison_operator": "LT",
+ "error_value": "80"
+ },
+ {
+ "metric": "new_duplicated_lines_density",
+ "comparison_operator": "GT",
+ "error_value": "3"
+ }
+ ]
+ },
+ {
+ "uuid": "uuid-1",
+ "caycStatus": "compliant",
+ "conditions": [
+ {
+ "metric": "new_coverage",
+ "comparison_operator": "LT",
+ "error_value": "80"
+ },
+ {
+ "metric": "new_duplicated_lines_density",
+ "comparison_operator": "GT",
+ "error_value": "3"
+ }
+ ]
+ },
+ {
+ "uuid": "uuid-2",
+ "caycStatus": "over-compliant",
+ "conditions": [
+ {
+ "metric": "new_coverage",
+ "comparison_operator": "LT",
+ "error_value": "80"
+ },
+ {
+ "metric": "new_duplicated_lines_density",
+ "comparison_operator": "GT",
+ "error_value": "3"
+ }
+ ]
+ }
+ ]
+ }
""");
}
@@ -693,9 +745,15 @@ public class TelemetryDataJsonWriterTest {
}
private List<TelemetryData.QualityGate> attachQualityGates() {
- return List.of(new TelemetryData.QualityGate("uuid-0", "non-compliant"),
- new TelemetryData.QualityGate("uuid-1", "compliant"),
- new TelemetryData.QualityGate("uuid-2", "over-compliant"));
+ List<Condition> qualityGateConditions = attachQualityGateConditions();
+ return List.of(new TelemetryData.QualityGate("uuid-0", "non-compliant", qualityGateConditions),
+ new TelemetryData.QualityGate("uuid-1", "compliant", qualityGateConditions),
+ new TelemetryData.QualityGate("uuid-2", "over-compliant", qualityGateConditions));
+ }
+
+ private List<Condition> attachQualityGateConditions() {
+ return List.of(new Condition("new_coverage", fromDbValue("LT"), "80"),
+ new Condition("new_duplicated_lines_density", fromDbValue("GT"), "3"));
}
private List<TelemetryData.Branch> attachBranches() {