aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java36
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConditionsUpdaterTest.java384
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateConditionActionTest.java38
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/UpdateConditionActionTest.java42
-rw-r--r--tests/src/test/java/org/sonarqube/tests/qualityGate/QualityGateTest.java268
-rw-r--r--tests/src/test/java/util/ItUtils.java14
8 files changed, 490 insertions, 298 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java
index d91c1c837e0..0a70ed55ad6 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java
@@ -38,7 +38,9 @@ import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating;
import org.sonar.server.exceptions.NotFoundException;
import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.lang.Double.parseDouble;
import static java.lang.Integer.parseInt;
+import static java.lang.Long.parseLong;
import static java.lang.String.format;
import static java.util.Arrays.stream;
import static org.sonar.api.measures.Metric.ValueType.RATING;
@@ -115,6 +117,9 @@ public class QualityGateConditionsUpdater {
checkOperator(metric, operator, errors);
checkThresholds(warningThreshold, errorThreshold, errors);
checkPeriod(metric, period, errors);
+
+ validateThresholdValues(metric, warningThreshold, errors);
+ validateThresholdValues(metric, errorThreshold, errors);
checkRatingMetric(metric, warningThreshold, errorThreshold, period, errors);
checkRequest(errors.isEmpty(), errors);
}
@@ -159,6 +164,37 @@ public class QualityGateConditionsUpdater {
: format("Condition on metric '%s' over leak period already exists.", metric.getShortName()));
}
+ private static void validateThresholdValues(MetricDto metric, @Nullable String value, List<String> errors) {
+ if (value == null) {
+ return;
+ }
+ try {
+ ValueType valueType = ValueType.valueOf(metric.getValueType());
+ switch (valueType) {
+ case BOOL:
+ case INT:
+ case RATING:
+ parseInt(value);
+ return;
+ case MILLISEC:
+ case WORK_DUR:
+ parseLong(value);
+ return;
+ case FLOAT:
+ case PERCENT:
+ parseDouble(value);
+ return;
+ case STRING:
+ case LEVEL:
+ return;
+ default:
+ throw new IllegalArgumentException(format("Unsupported value type %s. Cannot convert condition value", valueType));
+ }
+ } catch (Exception e) {
+ errors.add(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
+ }
+ }
+
private static void checkRatingMetric(MetricDto metric, @Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period, List<String> errors) {
if (!metric.getValueType().equals(RATING.name())) {
return;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java
index ef9d4d6ee6d..0b40b6c776e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java
@@ -31,6 +31,7 @@ import org.sonar.server.qualitygate.QualityGateConditionsUpdater;
import org.sonar.server.qualitygate.QualityGateFinder;
import org.sonarqube.ws.Qualitygates.CreateConditionResponse;
+import static com.google.common.base.Strings.emptyToNull;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.server.qualitygate.ws.QualityGatesWs.addConditionParams;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_CREATE_CONDITION;
@@ -89,7 +90,7 @@ public class CreateConditionAction implements QualityGatesWsAction {
OrganizationDto organization = wsSupport.getOrganization(dbSession, request);
QGateWithOrgDto qualityGate = qualityGateFinder.getByOrganizationAndId(dbSession, organization, gateId);
wsSupport.checkCanEdit(qualityGate);
- QualityGateConditionDto condition = qualityGateConditionsUpdater.createCondition(dbSession, qualityGate, metric, operator, warning, error, period);
+ QualityGateConditionDto condition = qualityGateConditionsUpdater.createCondition(dbSession, qualityGate, metric, operator, emptyToNull(warning), emptyToNull(error), period);
CreateConditionResponse.Builder createConditionResponse = CreateConditionResponse.newBuilder()
.setId(condition.getId())
.setMetric(condition.getMetricKey())
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java
index d5365ef5423..dcdb8b6e29f 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java
@@ -31,6 +31,7 @@ import org.sonar.server.qualitygate.QualityGateConditionsUpdater;
import org.sonarqube.ws.Qualitygates.UpdateConditionResponse;
import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Strings.emptyToNull;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.server.qualitygate.ws.QualityGatesWs.addConditionParams;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_UPDATE_CONDITION;
@@ -88,7 +89,7 @@ public class UpdateConditionAction implements QualityGatesWsAction {
QGateWithOrgDto qualityGateDto = dbClient.qualityGateDao().selectByOrganizationAndId(dbSession, organization, condition.getQualityGateId());
checkState(qualityGateDto != null, "Condition '%s' is linked to an unknown quality gate '%s'", id, condition.getQualityGateId());
wsSupport.checkCanEdit(qualityGateDto);
- QualityGateConditionDto updatedCondition = qualityGateConditionsUpdater.updateCondition(dbSession, condition, metric, operator, warning, error, period);
+ QualityGateConditionDto updatedCondition = qualityGateConditionsUpdater.updateCondition(dbSession, condition, metric, operator, emptyToNull(warning), emptyToNull(error), period);
UpdateConditionResponse.Builder updateConditionResponse = UpdateConditionResponse.newBuilder()
.setId(updatedCondition.getId())
.setMetric(updatedCondition.getMetricKey())
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConditionsUpdaterTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConditionsUpdaterTest.java
index 74c4583f7a9..22693231eec 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConditionsUpdaterTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConditionsUpdaterTest.java
@@ -23,30 +23,31 @@ import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import javax.annotation.Nullable;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.sonar.api.measures.Metric;
import org.sonar.api.utils.System2;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.qualitygate.QualityGateConditionDto;
-import org.sonar.db.qualitygate.QualityGateDbTester;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
+import static java.lang.String.format;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
+import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY;
+import static org.sonar.api.measures.Metric.ValueType.BOOL;
import static org.sonar.api.measures.Metric.ValueType.DATA;
+import static org.sonar.api.measures.Metric.ValueType.FLOAT;
import static org.sonar.api.measures.Metric.ValueType.INT;
+import static org.sonar.api.measures.Metric.ValueType.MILLISEC;
+import static org.sonar.api.measures.Metric.ValueType.PERCENT;
import static org.sonar.api.measures.Metric.ValueType.RATING;
-import static org.sonar.db.metric.MetricTesting.newMetricDto;
-import static org.sonar.server.computation.task.projectanalysis.metric.Metric.MetricType.PERCENT;
+import static org.sonar.api.measures.Metric.ValueType.WORK_DUR;
@RunWith(DataProviderRunner.class)
public class QualityGateConditionsUpdaterTest {
@@ -57,234 +58,351 @@ public class QualityGateConditionsUpdaterTest {
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
- DbClient dbClient = db.getDbClient();
- DbSession dbSession = db.getSession();
- QualityGateDbTester qualityGateDbTester = new QualityGateDbTester(db);
-
- QualityGateDto qualityGateDto;
- MetricDto coverageMetricDto = newMetricDto()
- .setKey("coverage")
- .setShortName("Coverage")
- .setValueType(PERCENT.name())
- .setHidden(false);
-
- MetricDto ratingMetricDto = newMetricDto()
- .setKey("reliability_rating")
- .setShortName("Reliability Rating")
- .setValueType(RATING.name())
- .setHidden(false);
-
- QualityGateConditionsUpdater underTest = new QualityGateConditionsUpdater(dbClient);
-
- @Before
- public void setUp() throws Exception {
- qualityGateDto = qualityGateDbTester.insertQualityGate(db.getDefaultOrganization());
- dbClient.metricDao().insert(dbSession, coverageMetricDto, ratingMetricDto);
- dbSession.commit();
- }
+ private QualityGateConditionsUpdater underTest = new QualityGateConditionsUpdater(db.getDbClient());
@Test
public void create_warning_condition_without_period() {
- QualityGateConditionDto result = underTest.createCondition(dbSession, qualityGateDto, "coverage", "LT", "90", null, null);
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
+ QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "90", null, null);
- verifyCondition(result, coverageMetricDto.getId(), "LT", "90", null, null);
+ verifyCondition(result, qualityGate, metric, "LT", "90", null, null);
}
@Test
- public void create_error_condition_with_period() {
- MetricDto metricDto = dbClient.metricDao().insert(dbSession, newMetricDto()
- .setKey("new_coverage")
- .setValueType(INT.name())
- .setHidden(false));
- dbSession.commit();
+ public void create_error_condition_on_leak_period() {
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey("new_coverage").setValueType(INT.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
- QualityGateConditionDto result = underTest.createCondition(dbSession, qualityGateDto, "new_coverage", "LT", null, "80", 1);
+ QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", null, "80", 1);
- verifyCondition(result, metricDto.getId(), "LT", null, "80", 1);
+ verifyCondition(result, qualityGate, metric, "LT", null, "80", 1);
}
@Test
public void fail_to_create_condition_when_condition_on_same_metric_already_exist() {
- dbClient.gateConditionDao().insert(new QualityGateConditionDto()
- .setQualityGateId(qualityGateDto.getId())
- .setMetricId(coverageMetricDto.getId())
- .setPeriod(null),
- dbSession);
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ db.qualityGates().addCondition(qualityGate, metric);
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Condition on metric 'Coverage' already exists.");
- underTest.createCondition(dbSession, qualityGateDto, coverageMetricDto.getKey(), "LT", "90", null, null);
+ expectedException.expectMessage(format("Condition on metric '%s' already exists.", metric.getShortName()));
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "90", null, null);
}
@Test
public void fail_to_create_condition_when_condition_on_same_metric_and_on_leak_period_already_exist() {
- dbClient.gateConditionDao().insert(new QualityGateConditionDto()
- .setQualityGateId(qualityGateDto.getId())
- .setMetricId(coverageMetricDto.getId())
- .setPeriod(1),
- dbSession);
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ db.qualityGates().addCondition(qualityGate, metric, c -> c.setPeriod(1));
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Condition on metric 'Coverage' over leak period already exists.");
- underTest.createCondition(dbSession, qualityGateDto, coverageMetricDto.getKey(), "LT", "90", null, 1);
+ expectedException.expectMessage(format("Condition on metric '%s' over leak period already exists.", metric.getShortName()));
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "90", null, 1);
}
@Test
public void fail_to_create_condition_on_missing_metric() {
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
expectedException.expect(NotFoundException.class);
expectedException.expectMessage("There is no metric with key=new_coverage");
- underTest.createCondition(dbSession, qualityGateDto, "new_coverage", "LT", null, "80", 2);
+
+ underTest.createCondition(db.getSession(), qualityGate, "new_coverage", "LT", null, "80", 2);
}
@Test
@UseDataProvider("invalid_metrics")
public void fail_to_create_condition_on_invalid_metric(String metricKey, Metric.ValueType valueType, boolean hidden) {
- dbClient.metricDao().insert(dbSession, newMetricDto()
- .setKey(metricKey)
- .setValueType(valueType.name())
- .setHidden(hidden));
- dbSession.commit();
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey(metricKey).setValueType(valueType.name()).setHidden(hidden));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Metric '" + metricKey + "' cannot be used to define a condition.");
- underTest.createCondition(dbSession, qualityGateDto, metricKey, "EQ", null, "80", null);
+ expectedException.expectMessage(format("Metric '%s' cannot be used to define a condition.", metric.getKey()));
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, "80", null);
}
@Test
public void fail_to_create_condition_on_not_allowed_operator() {
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Operator UNKNOWN is not allowed for metric type PERCENT.");
- underTest.createCondition(dbSession, qualityGateDto, "coverage", "UNKNOWN", null, "80", 2);
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "UNKNOWN", null, "80", 2);
}
@Test
public void fail_to_create_condition_on_missing_period() {
- dbClient.metricDao().insert(dbSession, newMetricDto()
- .setKey("new_coverage")
- .setValueType(INT.name())
- .setHidden(false));
- dbSession.commit();
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey("new_coverage").setValueType(INT.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("A period must be selected for differential metrics.");
- underTest.createCondition(dbSession, qualityGateDto, "new_coverage", "EQ", null, "90", null);
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, "90", null);
}
@Test
public void fail_to_create_condition_on_invalid_period() {
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey("new_coverage").setValueType(INT.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("The only valid quality gate period is 1, the leak period.");
- underTest.createCondition(dbSession, qualityGateDto, "coverage", "EQ", null, "90", 6);
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, "90", 6);
}
@Test
public void create_condition_on_rating_metric() {
- QualityGateConditionDto result = underTest.createCondition(dbSession, qualityGateDto, ratingMetricDto.getKey(), "GT", null, "3", null);
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
- verifyCondition(result, ratingMetricDto.getId(), "GT", null, "3", null);
+ QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "3", null);
+
+ verifyCondition(result, qualityGate, metric, "GT", null, "3", null);
}
@Test
public void fail_to_create_condition_on_rating_metric_on_leak_period() {
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("The metric 'Reliability Rating' cannot be used on the leak period");
- underTest.createCondition(dbSession, qualityGateDto, ratingMetricDto.getKey(), "GT", null, "3", 1);
+ expectedException.expectMessage(format("The metric '%s' cannot be used on the leak period", metric.getShortName()));
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "3", 1);
}
@Test
public void fail_to_create_warning_condition_on_invalid_rating_metric() {
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("'6' is not a valid rating");
- underTest.createCondition(dbSession, qualityGateDto, ratingMetricDto.getKey(), "GT", "6", null, null);
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "6", null, null);
}
@Test
public void fail_to_create_error_condition_on_invalid_rating_metric() {
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("'80' is not a valid rating");
- underTest.createCondition(dbSession, qualityGateDto, ratingMetricDto.getKey(), "GT", null, "80", null);
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "80", null);
}
@Test
public void fail_to_create_condition_on_greater_than_E() {
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("There's no worse rating than E (5)");
- underTest.createCondition(dbSession, qualityGateDto, ratingMetricDto.getKey(), "GT", "5", null, null);
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "5", null, null);
+ }
+
+ @Test
+ @UseDataProvider("valid_values")
+ public void create_warning_condition(Metric.ValueType valueType, String value) {
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
+ QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", value, null, null);
+
+ verifyCondition(result, qualityGate, metric, "EQ", value, null, null);
+ }
+
+ @Test
+ @UseDataProvider("valid_values")
+ public void create_error_condition(Metric.ValueType valueType, String value) {
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
+ QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, value, null);
+
+ verifyCondition(result, qualityGate, metric, "EQ", null, value, null);
+ }
+
+ @Test
+ @UseDataProvider("invalid_values")
+ public void fail_to_create_warning_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) {
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", value, null, null);
+ }
+
+ @Test
+ @UseDataProvider("invalid_values")
+ public void fail_to_create_error_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) {
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, value, null);
}
@Test
public void update_condition() {
- QualityGateConditionDto condition = insertCondition(coverageMetricDto.getId(), "LT", null, "80", null);
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
- QualityGateConditionDto result = underTest.updateCondition(dbSession, condition, "coverage", "GT", "60", null, 1);
+ QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60", null, 1);
- verifyCondition(result, coverageMetricDto.getId(), "GT", "60", null, 1);
+ verifyCondition(result, qualityGate, metric, "GT", "60", null, 1);
}
@Test
public void update_condition_over_leak_period() {
- QualityGateConditionDto condition = insertCondition(coverageMetricDto.getId(), "GT", "80", null, 1);
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("GT").setWarningThreshold("80").setErrorThreshold(null).setPeriod(1));
- QualityGateConditionDto result = underTest.updateCondition(dbSession, condition, "coverage", "LT", null, "80", null);
+ QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "LT", null, "80", null);
- verifyCondition(result, coverageMetricDto.getId(), "LT", null, "80", null);
+ verifyCondition(result, qualityGate, metric, "LT", null, "80", null);
}
@Test
public void update_condition_on_rating_metric() {
- QualityGateConditionDto condition = insertCondition(ratingMetricDto.getId(), "LT", null, "3", null);
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("LT").setWarningThreshold("80").setErrorThreshold(null).setPeriod(1));
- QualityGateConditionDto result = underTest.updateCondition(dbSession, condition, ratingMetricDto.getKey(), "GT", "4", null, null);
+ QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null, null);
- verifyCondition(result, ratingMetricDto.getId(), "GT", "4", null, null);
+ verifyCondition(result, qualityGate, metric, "GT", "4", null, null);
}
@Test
public void fail_to_update_condition_on_rating_metric_on_leak_period() {
- QualityGateConditionDto condition = insertCondition(ratingMetricDto.getId(), "LT", null, "3", null);
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("3").setPeriod(null));
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("The metric 'Reliability Rating' cannot be used on the leak period");
- underTest.updateCondition(dbSession, condition, ratingMetricDto.getKey(), "GT", "4", null, 1);
+ expectedException.expectMessage(format("The metric '%s' cannot be used on the leak period", metric.getShortName()));
+
+ underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null, 1);
}
@Test
public void fail_to_update_condition_on_rating_metric_on_not_core_rating_metric() {
- MetricDto metricDto = dbClient.metricDao().insert(dbSession, newMetricDto().setKey("rating_metric")
- .setShortName("Not core rating")
- .setValueType(RATING.name()).setHidden(false));
- QualityGateConditionDto condition = insertCondition(metricDto.getId(), "LT", null, "3", null);
- dbSession.commit();
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey("not_core_rating_metric").setValueType(RATING.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("3").setPeriod(null));
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("The metric 'Not core rating' cannot be used");
- underTest.updateCondition(dbSession, condition, metricDto.getKey(), "GT", "4", null, 1);
+ expectedException.expectMessage(format("The metric '%s' cannot be used", metric.getShortName()));
+
+ underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null, 1);
}
@Test
@UseDataProvider("invalid_metrics")
public void fail_to_update_condition_on_invalid_metric(String metricKey, Metric.ValueType valueType, boolean hidden) {
- MetricDto metricDto = dbClient.metricDao().insert(dbSession, newMetricDto()
- .setKey(metricKey)
- .setValueType(valueType.name())
- .setHidden(hidden));
- QualityGateConditionDto condition = insertCondition(metricDto.getId(), "LT", null, "80", null);
- dbSession.commit();
+ MetricDto metric = db.measures().insertMetric(m -> m.setKey(metricKey).setValueType(valueType.name()).setHidden(hidden));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Metric '" + metricKey + "' cannot be used to define a condition.");
- underTest.updateCondition(dbSession, condition, metricDto.getKey(), "GT", "60", null, 1);
+ expectedException.expectMessage(format("Metric '%s' cannot be used to define a condition.", metric.getKey()));
+
+ underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60", null, 1);
}
@Test
public void fail_to_update_condition_when_condition_on_same_metric_already_exist() {
- QualityGateConditionDto conditionNotOnLeakPeriod = insertCondition(coverageMetricDto.getId(), "GT", "80", null, null);
- QualityGateConditionDto conditionOnLeakPeriod = insertCondition(coverageMetricDto.getId(), "GT", "80", null, 1);
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto conditionNotOnLeakPeriod = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("GT").setWarningThreshold("80").setErrorThreshold(null).setPeriod(null));
+ QualityGateConditionDto conditionOnLeakPeriod = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("GT").setWarningThreshold("80").setErrorThreshold(null).setPeriod(1));
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Condition on metric 'Coverage' over leak period already exists.");
+ expectedException.expectMessage(format("Condition on metric '%s' over leak period already exists.", metric.getShortName()));
+
// Update condition not on leak period to be on leak period => will fail as this condition already exist
- underTest.updateCondition(dbSession, conditionNotOnLeakPeriod, coverageMetricDto.getKey(), "GT", "80", null, 1);
+ underTest.updateCondition(db.getSession(), conditionNotOnLeakPeriod, metric.getKey(), "GT", "80", null, 1);
+ }
+
+ @Test
+ @UseDataProvider("valid_values")
+ public void update_warning_condition(Metric.ValueType valueType, String value) {
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
+
+ QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value, null, null);
+
+ verifyCondition(result, qualityGate, metric, "EQ", value, null, null);
+ }
+
+ @Test
+ @UseDataProvider("valid_values")
+ public void update_error_condition(Metric.ValueType valueType, String value) {
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
+
+ QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", null, value, null);
+
+ verifyCondition(result, qualityGate, metric, "EQ", null, value, null);
+ }
+
+ @Test
+ @UseDataProvider("invalid_values")
+ public void fail_to_update_warning_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) {
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
+
+ underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value, null, null);
+ }
+
+ @Test
+ @UseDataProvider("invalid_values")
+ public void fail_to_update_error_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) {
+ MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false));
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
+
+ underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", null, value, null);
}
@DataProvider
@@ -296,30 +414,42 @@ public class QualityGateConditionsUpdaterTest {
};
}
- private QualityGateConditionDto insertCondition(long metricId, String operator, @Nullable String warning, @Nullable String error,
+ @DataProvider
+ public static Object[][] valid_values() {
+ return new Object[][] {
+ {INT, "10"},
+ {BOOL, "1"},
+ {MILLISEC, "1000"},
+ {WORK_DUR, "1000"},
+ {FLOAT, "5.12"},
+ {PERCENT, "10.30"},
+ };
+ }
+
+ @DataProvider
+ public static Object[][] invalid_values() {
+ return new Object[][] {
+ {INT, "ABCD"},
+ {BOOL, "ABCD"},
+ {MILLISEC, "ABCD"},
+ {WORK_DUR, "ABCD"},
+ {FLOAT, "ABCD"},
+ {PERCENT, "ABCD"},
+ };
+ }
+
+ private void verifyCondition(QualityGateConditionDto dto, QualityGateDto qualityGate, MetricDto metric, String operator, @Nullable String warning, @Nullable String error,
@Nullable Integer period) {
- QualityGateConditionDto qualityGateConditionDto = new QualityGateConditionDto().setQualityGateId(qualityGateDto.getId())
- .setMetricId(metricId)
- .setOperator(operator)
- .setWarningThreshold(warning)
- .setErrorThreshold(error)
- .setPeriod(period);
- dbClient.gateConditionDao().insert(qualityGateConditionDto, dbSession);
- dbSession.commit();
- return qualityGateConditionDto;
- }
-
- private void verifyCondition(QualityGateConditionDto dto, int metricId, String operator, @Nullable String warning, @Nullable String error, @Nullable Integer period) {
- QualityGateConditionDto reloaded = dbClient.gateConditionDao().selectById(dto.getId(), dbSession);
- assertThat(reloaded.getQualityGateId()).isEqualTo(qualityGateDto.getId());
- assertThat(reloaded.getMetricId()).isEqualTo(metricId);
+ QualityGateConditionDto reloaded = db.getDbClient().gateConditionDao().selectById(dto.getId(), db.getSession());
+ assertThat(reloaded.getQualityGateId()).isEqualTo(qualityGate.getId());
+ assertThat(reloaded.getMetricId()).isEqualTo(metric.getId().longValue());
assertThat(reloaded.getOperator()).isEqualTo(operator);
assertThat(reloaded.getWarningThreshold()).isEqualTo(warning);
assertThat(reloaded.getErrorThreshold()).isEqualTo(error);
assertThat(reloaded.getPeriod()).isEqualTo(period);
- assertThat(dto.getQualityGateId()).isEqualTo(qualityGateDto.getId());
- assertThat(dto.getMetricId()).isEqualTo(metricId);
+ assertThat(dto.getQualityGateId()).isEqualTo(qualityGate.getId());
+ assertThat(dto.getMetricId()).isEqualTo(metric.getId().longValue());
assertThat(dto.getOperator()).isEqualTo(operator);
assertThat(dto.getWarningThreshold()).isEqualTo(warning);
assertThat(dto.getErrorThreshold()).isEqualTo(error);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateConditionActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateConditionActionTest.java
index f4f885a070a..01f3bc60e20 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateConditionActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateConditionActionTest.java
@@ -148,6 +148,44 @@ public class CreateConditionActionTest {
}
@Test
+ public void create_warning_condition_with_empty_string_on_error() {
+ OrganizationDto organization = db.organizations().insert();
+ logInAsQualityGateAdmin(organization);
+ QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+ MetricDto metric = insertMetric();
+
+ ws.newRequest()
+ .setParam(PARAM_GATE_ID, qualityGate.getId().toString())
+ .setParam(PARAM_METRIC, metric.getKey())
+ .setParam(PARAM_OPERATOR, "LT")
+ .setParam(PARAM_WARNING, "90")
+ .setParam(PARAM_ERROR, "")
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+
+ assertCondition(qualityGate, metric, "LT", "90", null, null);
+ }
+
+ @Test
+ public void create_error_condition_with_empty_string_on_warning() {
+ OrganizationDto organization = db.organizations().insert();
+ logInAsQualityGateAdmin(organization);
+ QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+ MetricDto metric = insertMetric();
+
+ ws.newRequest()
+ .setParam(PARAM_GATE_ID, qualityGate.getId().toString())
+ .setParam(PARAM_METRIC, metric.getKey())
+ .setParam(PARAM_OPERATOR, "LT")
+ .setParam(PARAM_WARNING, "")
+ .setParam(PARAM_ERROR, "90")
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+
+ assertCondition(qualityGate, metric, "LT", null, "90", null);
+ }
+
+ @Test
public void fail_to_update_built_in_quality_gate() {
OrganizationDto organization = db.organizations().insert();
logInAsQualityGateAdmin(organization);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/UpdateConditionActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/UpdateConditionActionTest.java
index 5b783fc0129..f01d7f6ac91 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/UpdateConditionActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/UpdateConditionActionTest.java
@@ -152,6 +152,48 @@ public class UpdateConditionActionTest {
}
@Test
+ public void update_warning_condition_with_empty_string_on_error() {
+ OrganizationDto organization = db.organizations().insert();
+ userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+ QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+ MetricDto metric = insertMetric();
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
+
+ ws.newRequest()
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .setParam(PARAM_ID, Long.toString(condition.getId()))
+ .setParam(PARAM_METRIC, metric.getKey())
+ .setParam(PARAM_OPERATOR, "LT")
+ .setParam(PARAM_WARNING, "90")
+ .setParam(PARAM_ERROR, "")
+ .execute();
+
+ assertCondition(qualityGate, metric, "LT", "90", null, null);
+ }
+
+ @Test
+ public void update_error_condition_with_empty_string_on_warning() {
+ OrganizationDto organization = db.organizations().insert();
+ userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+ QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+ MetricDto metric = insertMetric();
+ QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
+ c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
+
+ ws.newRequest()
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .setParam(PARAM_ID, Long.toString(condition.getId()))
+ .setParam(PARAM_METRIC, metric.getKey())
+ .setParam(PARAM_OPERATOR, "LT")
+ .setParam(PARAM_ERROR, "90")
+ .setParam(PARAM_WARNING, "")
+ .execute();
+
+ assertCondition(qualityGate, metric, "LT", null, "90", null);
+ }
+
+ @Test
public void test_response() {
OrganizationDto organization = db.organizations().insert();
userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
diff --git a/tests/src/test/java/org/sonarqube/tests/qualityGate/QualityGateTest.java b/tests/src/test/java/org/sonarqube/tests/qualityGate/QualityGateTest.java
index 7160ac819d8..05f7871f364 100644
--- a/tests/src/test/java/org/sonarqube/tests/qualityGate/QualityGateTest.java
+++ b/tests/src/test/java/org/sonarqube/tests/qualityGate/QualityGateTest.java
@@ -19,6 +19,7 @@
*/
package org.sonarqube.tests.qualityGate;
+import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.BuildResult;
@@ -34,49 +35,45 @@ import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.FileUtils;
-import org.junit.After;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
-import org.sonar.wsclient.qualitygate.NewCondition;
-import org.sonar.wsclient.qualitygate.QualityGate;
-import org.sonar.wsclient.qualitygate.QualityGateClient;
+import org.sonarqube.qa.util.QGateTester;
import org.sonarqube.qa.util.Tester;
-import org.sonarqube.qa.util.TesterSession;
-import org.sonarqube.ws.Ce;
import org.sonarqube.ws.Measures.Measure;
-import org.sonarqube.ws.MediaTypes;
-import org.sonarqube.ws.Organizations.Organization;
import org.sonarqube.ws.Projects.CreateWsResponse.Project;
import org.sonarqube.ws.Qualitygates;
import org.sonarqube.ws.Qualitygates.CreateResponse;
+import org.sonarqube.ws.Qualitygates.ListWsResponse.QualityGate;
import org.sonarqube.ws.Qualitygates.ProjectStatusResponse;
import org.sonarqube.ws.Users;
-import org.sonarqube.ws.client.GetRequest;
-import org.sonarqube.ws.client.PostRequest;
-import org.sonarqube.ws.client.WsResponse;
+import org.sonarqube.ws.client.ce.TaskRequest;
+import org.sonarqube.ws.client.metrics.CreateRequest;
+import org.sonarqube.ws.client.metrics.DeleteRequest;
import org.sonarqube.ws.client.permissions.AddUserRequest;
import org.sonarqube.ws.client.qualitygates.CreateConditionRequest;
+import org.sonarqube.ws.client.qualitygates.DeleteConditionRequest;
+import org.sonarqube.ws.client.qualitygates.DestroyRequest;
+import org.sonarqube.ws.client.qualitygates.ListRequest;
import org.sonarqube.ws.client.qualitygates.ProjectStatusRequest;
-import org.sonarqube.ws.client.qualitygates.QualitygatesService;
import org.sonarqube.ws.client.qualitygates.SelectRequest;
+import org.sonarqube.ws.client.qualitygates.SetAsDefaultRequest;
import org.sonarqube.ws.client.qualitygates.UpdateConditionRequest;
+import static java.lang.String.format;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
import static org.sonarqube.ws.Qualitygates.ProjectStatusResponse.Status.ERROR;
import static util.ItUtils.concat;
+import static util.ItUtils.expectHttpError;
import static util.ItUtils.extractCeTaskId;
import static util.ItUtils.getMeasure;
-import static util.ItUtils.newProjectKey;
import static util.ItUtils.projectDir;
public class QualityGateTest {
private static final String TASK_STATUS_SUCCESS = "SUCCESS";
- private static final String QG_STATUS_NO_QG = "null";
private static final String QG_STATUS_OK = "OK";
private static final String QG_STATUS_ERROR = "ERROR";
private static final String QG_STATUS_WARN = "WARN";
@@ -85,114 +82,101 @@ public class QualityGateTest {
public static Orchestrator orchestrator = QualityGateSuite.ORCHESTRATOR;
@Rule
- public Tester tester = new Tester(orchestrator)
- // all the tests of QualityGateSuite must disable organizations
- .disableOrganizations();
-
- private QualityGate defaultGate;
-
- @Before
- public void setUp() {
- defaultGate = qgClient().list().defaultGate();
- }
-
- @After
- public void tearDown() {
- if (defaultGate != null) {
- qgClient().setDefault(defaultGate.id());
- }
- }
+ public Tester tester = new Tester(orchestrator).disableOrganizations();
@Test
public void status_ok_if_empty_gate() throws Exception {
- Qualitygates.CreateResponse empty = tester.qGates().generate();
- qgClient().setDefault(empty.getId());
-
- String projectKey = newProjectKey();
- BuildResult buildResult = executeAnalysis(projectKey);
+ Project project = tester.projects().provision();
+ Qualitygates.CreateResponse qualityGate = tester.qGates().generate();
+ tester.qGates().associateProject(qualityGate, project);
+ BuildResult buildResult = executeAnalysis(project.getKey());
- verifyQGStatusInPostTask(buildResult, projectKey, TASK_STATUS_SUCCESS, QG_STATUS_OK);
+ verifyQGStatusInPostTask(buildResult, project.getKey(), TASK_STATUS_SUCCESS, QG_STATUS_OK);
- assertThat(getGateStatusMeasure(projectKey).getValue()).isEqualTo("OK");
+ assertThat(getGateStatusMeasure(project.getKey()).getValue()).isEqualTo("OK");
}
@Test
public void test_status_ok() throws IOException {
- Qualitygates.CreateResponse simple = tester.qGates().generate();
- qgClient().setDefault(simple.getId());
- qgClient().createCondition(NewCondition.create(simple.getId()).metricKey("ncloc").operator("GT").warningThreshold("40"));
-
- String projectKey = newProjectKey();
- BuildResult buildResult = executeAnalysis(projectKey);
+ Project project = tester.projects().provision();
+ Qualitygates.CreateResponse qualityGate = tester.qGates().generate();
+ tester.qGates().associateProject(qualityGate, project);
+ tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric("ncloc").setOp("GT").setWarning("40"));
+ BuildResult buildResult = executeAnalysis(project.getKey());
- verifyQGStatusInPostTask(buildResult, projectKey, TASK_STATUS_SUCCESS, QG_STATUS_OK);
+ verifyQGStatusInPostTask(buildResult, project.getKey(), TASK_STATUS_SUCCESS, QG_STATUS_OK);
- assertThat(getGateStatusMeasure(projectKey).getValue()).isEqualTo("OK");
+ assertThat(getGateStatusMeasure(project.getKey()).getValue()).isEqualTo("OK");
}
@Test
public void test_status_warning() throws IOException {
- Qualitygates.CreateResponse simple = tester.qGates().generate();
- qgClient().setDefault(simple.getId());
- qgClient().createCondition(NewCondition.create(simple.getId()).metricKey("ncloc").operator("GT").warningThreshold("10"));
-
- String projectKey = newProjectKey();
- BuildResult buildResult = executeAnalysis(projectKey);
+ Project project = tester.projects().provision();
+ Qualitygates.CreateResponse qualityGate = tester.qGates().generate();
+ tester.qGates().associateProject(qualityGate, project);
+ tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric("ncloc").setOp("GT").setWarning("10"));
+ BuildResult buildResult = executeAnalysis(project.getKey());
- verifyQGStatusInPostTask(buildResult, projectKey, TASK_STATUS_SUCCESS, QG_STATUS_WARN);
+ verifyQGStatusInPostTask(buildResult, project.getKey(), TASK_STATUS_SUCCESS, QG_STATUS_WARN);
- assertThat(getGateStatusMeasure(projectKey).getValue()).isEqualTo("WARN");
+ assertThat(getGateStatusMeasure(project.getKey()).getValue()).isEqualTo("WARN");
}
@Test
public void test_status_error() throws IOException {
- Qualitygates.CreateResponse simple = tester.qGates().generate();
- qgClient().setDefault(simple.getId());
- qgClient().createCondition(NewCondition.create(simple.getId()).metricKey("ncloc").operator("GT").errorThreshold("10"));
-
- String projectKey = newProjectKey();
- BuildResult buildResult = executeAnalysis(projectKey);
+ Project project = tester.projects().provision();
+ Qualitygates.CreateResponse qualityGate = tester.qGates().generate();
+ tester.qGates().associateProject(qualityGate, project);
+ tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric("ncloc").setOp("GT").setError("10"));
+ BuildResult buildResult = executeAnalysis(project.getKey());
- verifyQGStatusInPostTask(buildResult, projectKey, TASK_STATUS_SUCCESS, QG_STATUS_ERROR);
+ verifyQGStatusInPostTask(buildResult, project.getKey(), TASK_STATUS_SUCCESS, QG_STATUS_ERROR);
- assertThat(getGateStatusMeasure(projectKey).getValue()).isEqualTo("ERROR");
+ assertThat(getGateStatusMeasure(project.getKey()).getValue()).isEqualTo("ERROR");
}
@Test
public void use_server_settings_instead_of_default_gate() throws IOException {
- Qualitygates.CreateResponse alert = tester.qGates().generate();
- qgClient().createCondition(NewCondition.create(alert.getId()).metricKey("ncloc").operator("GT").warningThreshold("10"));
- Qualitygates.CreateResponse error = tester.qGates().generate();
- qgClient().createCondition(NewCondition.create(error.getId()).metricKey("ncloc").operator("GT").errorThreshold("10"));
-
- qgClient().setDefault(alert.getId());
- String projectKey = newProjectKey();
- orchestrator.getServer().provisionProject(projectKey, projectKey);
- associateQualityGateToProject(error.getId(), projectKey);
+ QualityGate existingDefaultQualityGate = tester.qGates().service().list(new ListRequest()).getQualitygatesList()
+ .stream()
+ .filter(QualityGate::getIsDefault)
+ .findFirst()
+ .orElseThrow(() -> new IllegalStateException("No default quality gate found"));
+ try {
+ Qualitygates.CreateResponse defaultQualityGate = tester.qGates().generate();
+ tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(defaultQualityGate.getId())).setMetric("ncloc").setOp("GT").setWarning("10"));
+ tester.qGates().service().setAsDefault(new SetAsDefaultRequest().setId(Long.toString(defaultQualityGate.getId())));
- BuildResult buildResult = executeAnalysis(projectKey);
+ Project project = tester.projects().provision();
+ Qualitygates.CreateResponse qualityGate = tester.qGates().generate();
+ tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric("ncloc").setOp("GT").setError("10"));
+ tester.qGates().associateProject(qualityGate, project);
- verifyQGStatusInPostTask(buildResult, projectKey, TASK_STATUS_SUCCESS, QG_STATUS_ERROR);
+ BuildResult buildResult = executeAnalysis(project.getKey());
- assertThat(getGateStatusMeasure(projectKey).getValue()).isEqualTo("ERROR");
+ verifyQGStatusInPostTask(buildResult, project.getKey(), TASK_STATUS_SUCCESS, QG_STATUS_ERROR);
+ assertThat(getGateStatusMeasure(project.getKey()).getValue()).isEqualTo("ERROR");
+ } finally {
+ tester.qGates().service().setAsDefault(new SetAsDefaultRequest().setId(Long.toString(existingDefaultQualityGate.getId())));
+ }
}
@Test
public void conditions_on_multiple_metric_types() throws IOException {
- Qualitygates.CreateResponse allTypes = tester.qGates().generate();
- qgClient().createCondition(NewCondition.create(allTypes.getId()).metricKey("ncloc").operator("GT").warningThreshold("10"));
- qgClient().createCondition(NewCondition.create(allTypes.getId()).metricKey("duplicated_lines_density").operator("GT").warningThreshold("20"));
- qgClient().setDefault(allTypes.getId());
-
- String projectKey = newProjectKey();
- BuildResult buildResult = executeAnalysis(projectKey, "sonar.cpd.xoo.minimumLines", "2", "sonar.cpd.xoo.minimumTokens", "5");
+ Project project = tester.projects().provision();
+ Qualitygates.CreateResponse qualityGate = tester.qGates().generate();
+ tester.qGates().associateProject(qualityGate, project);
+ tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric("ncloc").setOp("GT").setWarning("10"));
+ tester.qGates().service()
+ .createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric("duplicated_lines_density").setOp("GT").setWarning("20"));
+ BuildResult buildResult = executeAnalysis(project.getKey(), "sonar.cpd.xoo.minimumLines", "2", "sonar.cpd.xoo.minimumTokens", "5");
- verifyQGStatusInPostTask(buildResult, projectKey, TASK_STATUS_SUCCESS, QG_STATUS_WARN);
+ verifyQGStatusInPostTask(buildResult, project.getKey(), TASK_STATUS_SUCCESS, QG_STATUS_WARN);
- Measure alertStatus = getGateStatusMeasure(projectKey);
+ Measure alertStatus = getGateStatusMeasure(project.getKey());
assertThat(alertStatus.getValue()).isEqualTo("WARN");
- String qualityGateDetailJson = getMeasure(orchestrator, projectKey, "quality_gate_details").getValue();
+ String qualityGateDetailJson = getMeasure(orchestrator, project.getKey(), "quality_gate_details").getValue();
assertThat(QualityGateDetails.parse(qualityGateDetailJson).getConditions())
.extracting(QualityGateDetails.Conditions::getMetric, QualityGateDetails.Conditions::getOp, QualityGateDetails.Conditions::getWarning)
.contains(tuple("ncloc", "GT", "10"), tuple("duplicated_lines_density", "GT", "20"));
@@ -200,19 +184,18 @@ public class QualityGateTest {
@Test
public void ad_hoc_build_break_strategy() throws IOException {
- Qualitygates.CreateResponse simple = tester.qGates().generate();
- qgClient().setDefault(simple.getId());
- qgClient().createCondition(NewCondition.create(simple.getId()).metricKey("ncloc").operator("GT").errorThreshold("7"));
-
- String projectKey = newProjectKey();
- BuildResult buildResult = executeAnalysis(projectKey);
+ Project project = tester.projects().provision();
+ Qualitygates.CreateResponse qualityGate = tester.qGates().generate();
+ tester.qGates().associateProject(qualityGate, project);
+ tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric("ncloc").setOp("GT").setError("7"));
+ BuildResult buildResult = executeAnalysis(project.getKey());
- verifyQGStatusInPostTask(buildResult, projectKey, TASK_STATUS_SUCCESS, QG_STATUS_ERROR);
+ verifyQGStatusInPostTask(buildResult, project.getKey(), TASK_STATUS_SUCCESS, QG_STATUS_ERROR);
String taskId = getTaskIdInLocalReport(projectDir("qualitygate/xoo-sample"));
- String analysisId = getAnalysisId(taskId);
+ String analysisId = tester.wsClient().ce().task(new TaskRequest().setId(taskId)).getTask().getAnalysisId();
- ProjectStatusResponse projectStatusWsResponse = tester.wsClient().qualitygates().projectStatus(new ProjectStatusRequest().setAnalysisId(analysisId));
+ ProjectStatusResponse projectStatusWsResponse = tester.qGates().service().projectStatus(new ProjectStatusRequest().setAnalysisId(analysisId));
ProjectStatusResponse.ProjectStatus projectStatus = projectStatusWsResponse.getProjectStatus();
assertThat(projectStatus.getStatus()).isEqualTo(ERROR);
assertThat(projectStatus.getConditionsCount()).isEqualTo(1);
@@ -223,52 +206,59 @@ public class QualityGateTest {
@Test
public void does_not_fail_when_condition_is_on_removed_metric() throws Exception {
- // create project
Project project = tester.projects().provision();
- String projectKey = project.getKey();
-
- // create custom metric
String customMetricKey = randomAlphabetic(10);
- createCustomIntMetric(customMetricKey);
+ tester.wsClient().metrics().create(new CreateRequest().setKey(customMetricKey).setName(customMetricKey).setType("INT"));
try {
// create quality gate
- Qualitygates.CreateResponse simple = tester.qGates().generate();
- Long qualityGateId = simple.getId();
- qgClient().createCondition(NewCondition.create(qualityGateId).metricKey(customMetricKey).operator("GT").warningThreshold("40"));
-
+ Qualitygates.CreateResponse qualityGate = tester.qGates().generate();
+ Long qualityGateId = qualityGate.getId();
+ tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric(customMetricKey).setOp("GT").setWarning("40"));
// delete custom metric
- deleteCustomMetric(customMetricKey);
+ tester.wsClient().metrics().delete(new DeleteRequest().setKeys(ImmutableList.of(customMetricKey)));
// run analysis
- tester.wsClient().qualitygates().select(new SelectRequest().setProjectKey(projectKey).setGateId(String.valueOf(qualityGateId)));
- BuildResult buildResult = executeAnalysis(projectKey);
+ tester.qGates().service().select(new SelectRequest().setProjectKey(project.getKey()).setGateId(String.valueOf(qualityGateId)));
+ BuildResult buildResult = executeAnalysis(project.getKey());
// verify quality gate
- verifyQGStatusInPostTask(buildResult, projectKey, TASK_STATUS_SUCCESS, QG_STATUS_OK);
- assertThat(getGateStatusMeasure(projectKey).getValue()).isEqualTo("OK");
+ verifyQGStatusInPostTask(buildResult, project.getKey(), TASK_STATUS_SUCCESS, QG_STATUS_OK);
+ assertThat(getGateStatusMeasure(project.getKey()).getValue()).isEqualTo("OK");
} finally {
- deleteCustomMetric(customMetricKey);
+ tester.wsClient().metrics().delete(new DeleteRequest().setKeys(ImmutableList.of(customMetricKey)));
}
}
@Test
public void administrate_quality_gate_with_gateadmin_permission() {
// user is quality gate admin of default organization
- Organization organization = tester.organizations().getDefaultOrganization();
- Users.CreateWsResponse.User user = tester.users().generateMember(organization);
- tester.wsClient().permissions().addUser(new AddUserRequest().setLogin(user.getLogin()).setPermission("gateadmin").setOrganization(organization.getKey()));
- TesterSession qGateAdminTester = tester.as(user.getLogin());
- QualitygatesService qGateService = qGateAdminTester.qGates().service();
+ Users.CreateWsResponse.User user = tester.users().generate();
+ tester.wsClient().permissions().addUser(new AddUserRequest().setLogin(user.getLogin()).setPermission("gateadmin"));
+ QGateTester qGateAdminTester = tester.as(user.getLogin()).qGates();
+
// perform administration operations
- CreateResponse qualityGate = qGateAdminTester.qGates().generate();
- Qualitygates.CreateConditionResponse condition = qGateService.createCondition(new CreateConditionRequest()
+ CreateResponse qualityGate = qGateAdminTester.generate();
+ Qualitygates.CreateConditionResponse condition = qGateAdminTester.service().createCondition(new CreateConditionRequest()
.setGateId(String.valueOf(qualityGate.getId())).setMetric("coverage").setOp("LT").setError("90"));
- qGateService.updateCondition(new UpdateConditionRequest()
+ qGateAdminTester.service().updateCondition(new UpdateConditionRequest()
.setId(String.valueOf(condition.getId())).setMetric("coverage").setOp("LT").setError("90").setWarning("80"));
- qGateAdminTester.wsClient().wsConnector().call(new PostRequest("api/qualitygates/set_as_default").setParam("id", qualityGate.getId()));
- qGateAdminTester.wsClient().wsConnector().call(new PostRequest("api/qualitygates/delete_condition").setParam("id", condition.getId()));
- qGateAdminTester.wsClient().wsConnector().call(new PostRequest("api/qualitygates/unset_default").setParam("id", qualityGate.getId()));
- qGateAdminTester.wsClient().wsConnector().call(new PostRequest("api/qualitygates/destroy").setParam("id", qualityGate.getId()));
+ qGateAdminTester.service().deleteCondition(new DeleteConditionRequest().setId(Long.toString(condition.getId())));
+ qGateAdminTester.service().destroy(new DestroyRequest().setId(Long.toString(qualityGate.getId())));
+ }
+
+ @Test
+ public void fail_to_create_and_update_conditions_when_using_invalid_values() {
+ Qualitygates.CreateResponse qualityGate = tester.qGates().generate();
+
+ expectHttpError(400,
+ format("Invalid value 'INVALID' for metric 'ncloc'"),
+ () -> tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric("ncloc").setOp("GT").setWarning("INVALID")));
+ expectHttpError(400,
+ format("User '%s' is not member of organization '%s'"),
+ () -> tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric("sqale_index").setOp("GT").setWarning("10d")));
+ expectHttpError(400,
+ format("User '%s' is not member of organization '%s'"),
+ () -> tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(Long.toString(qualityGate.getId())).setMetric("coverage").setOp("GT").setWarning("10%")));
}
private BuildResult executeAnalysis(String projectKey, String... keyValueProperties) {
@@ -287,16 +277,6 @@ public class QualityGateTest {
.contains("QualityGate[" + qgStatus + "]");
}
- private String getAnalysisId(String taskId) throws IOException {
- WsResponse activity = tester.wsClient()
- .wsConnector()
- .call(new GetRequest("api/ce/task")
- .setParam("id", taskId)
- .setMediaType(MediaTypes.PROTOBUF));
- Ce.TaskResponse activityWsResponse = Ce.TaskResponse.parseFrom(activity.contentStream());
- return activityWsResponse.getTask().getAnalysisId();
- }
-
private String getTaskIdInLocalReport(File projectDirectory) throws IOException {
File metadata = new File(projectDirectory, ".sonar/report-task.txt");
assertThat(metadata).exists().isFile();
@@ -312,18 +292,6 @@ public class QualityGateTest {
return getMeasure(orchestrator, projectKey, "alert_status");
}
- private QualityGateClient qgClient() {
- return orchestrator.getServer().adminWsClient().qualityGateClient();
- }
-
- private void associateQualityGateToProject(long qGateId, String projectKey) {
- tester.wsClient().wsConnector()
- .call(new PostRequest("api/qualitygates/select")
- .setParam("gateId", qGateId)
- .setParam("projectKey", projectKey))
- .failIfNotSuccessful();
- }
-
private static List<String> extractPosttaskPluginLogs(String taskUuid, Iterable<String> ceLogs) {
return StreamSupport.stream(ceLogs.spliterator(), false)
.filter(s -> s.contains("POSTASKPLUGIN: finished()"))
@@ -331,20 +299,6 @@ public class QualityGateTest {
.collect(Collectors.toList());
}
- private void createCustomIntMetric(String metricKey) {
- tester.wsClient().wsConnector().call(new PostRequest("api/metrics/create")
- .setParam("key", metricKey)
- .setParam("name", metricKey)
- .setParam("type", "INT"))
- .failIfNotSuccessful();
- }
-
- private void deleteCustomMetric(String metricKey) {
- tester.wsClient().wsConnector().call(new PostRequest("api/metrics/delete")
- .setParam("keys", metricKey))
- .failIfNotSuccessful();
- }
-
static class QualityGateDetails {
private String level;
diff --git a/tests/src/test/java/util/ItUtils.java b/tests/src/test/java/util/ItUtils.java
index a5c763180de..13f268a4697 100644
--- a/tests/src/test/java/util/ItUtils.java
+++ b/tests/src/test/java/util/ItUtils.java
@@ -85,7 +85,6 @@ import static com.sonar.orchestrator.container.Server.ADMIN_PASSWORD;
import static java.lang.Double.parseDouble;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
-import static java.util.Locale.ENGLISH;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
@@ -314,7 +313,7 @@ public class ItUtils {
}
/**
- * @deprecated no more needed as already done by n by {@link Tester#after()}
+ * @deprecated no more needed as already done by {@link Tester#after()}
*/
@Deprecated
public static void resetEmailSettings(Orchestrator orchestrator) {
@@ -323,7 +322,7 @@ public class ItUtils {
}
/**
- * @deprecated no more needed as already done by n by {@link Tester#after()}
+ * @deprecated no more needed as already done by {@link Tester#after()}
*/
@Deprecated
public static void resetPeriod(Orchestrator orchestrator) {
@@ -432,10 +431,6 @@ public class ItUtils {
.build().call(httpRequest);
}
- public static String newOrganizationKey() {
- return randomAlphabetic(32).toLowerCase(ENGLISH);
- }
-
public static String newProjectKey() {
return "key-" + randomAlphabetic(100);
}
@@ -499,11 +494,6 @@ public class ItUtils {
return sdf.format(d);
}
- public static String formatDateTime(Date d) {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
- return sdf.format(d);
- }
-
public static String extractCeTaskId(BuildResult buildResult) {
List<String> taskIds = extractCeTaskIds(buildResult);
checkState(taskIds.size() == 1, "More than one task id retrieved from logs");