private final QualityGate.EvaluationStatus status;
private final String metricKey;
private final QualityGate.Operator operator;
- @CheckForNull
private final String errorThreshold;
- @CheckForNull
- private final String warningThreshold;
private final boolean onLeakPeriod;
@CheckForNull
private final String value;
requireNonNull(builder.status, "status can not be null");
requireNonNull(builder.metricKey, "metricKey can not be null");
requireNonNull(builder.operator, "operator can not be null");
- verifyThresholds(builder);
+ requireNonNull(builder.errorThreshold, "errorThreshold can not be null");
verifyValue(builder);
this.status = builder.status;
this.metricKey = builder.metricKey;
this.operator = builder.operator;
this.errorThreshold = builder.errorThreshold;
- this.warningThreshold = builder.warningThreshold;
this.onLeakPeriod = builder.metricKey.startsWith("new_");
this.value = builder.value;
}
- private static void verifyThresholds(Builder builder) {
- checkArgument(
- builder.errorThreshold != null || builder.warningThreshold != null,
- "At least one of errorThreshold and warningThreshold must be non null");
- }
-
private static void verifyValue(Builder builder) {
if (builder.status == NO_VALUE) {
checkArgument(builder.value == null, "value must be null when status is %s", NO_VALUE);
public static class Builder {
private String metricKey;
private QualityGate.Operator operator;
- @CheckForNull
private String errorThreshold;
@CheckForNull
- private String warningThreshold;
- @CheckForNull
private String value;
private QualityGate.EvaluationStatus status;
return this;
}
+ /**
+ * @deprecated in 7.6. This method has no longer any effect.
+ */
+ @Deprecated
public Builder setWarningThreshold(String warningThreshold) {
- this.warningThreshold = warningThreshold;
return this;
}
return errorThreshold;
}
+ @Deprecated
@Override
public String getWarningThreshold() {
- return warningThreshold;
+ return null;
}
/**
", metricKey='" + metricKey + '\'' +
", operator=" + operator +
", errorThreshold='" + errorThreshold + '\'' +
- ", warningThreshold='" + warningThreshold + '\'' +
", value='" + value + '\'' +
'}';
}
.setMetricKey(metricKey)
.setOperator(convert(input.getOperator()))
.setErrorThreshold(input.getErrorThreshold())
- .setWarningThreshold(input.getWarningThreshold())
.setValue(conditionStatus.getValue())
.build();
}
return QualityGate.EvaluationStatus.NO_VALUE;
case OK:
return QualityGate.EvaluationStatus.OK;
- case WARN:
- return QualityGate.EvaluationStatus.WARN;
case ERROR:
return QualityGate.EvaluationStatus.ERROR;
default:
switch (status) {
case OK:
return QualityGate.Status.OK;
- case WARN:
- return QualityGate.Status.WARN;
case ERROR:
return QualityGate.Status.ERROR;
default:
public enum Level {
OK("Green"),
- WARN("Orange"),
ERROR("Red");
private final String colorName;
}
public Measure create(boolean value, @Nullable String data) {
- return new Measure(ValueType.BOOLEAN, developer, value ? 1.0d : 0.0d, data, null, qualityGateStatus, variation);
+ return new Measure(ValueType.BOOLEAN, developer, value ? 1.0D : 0.0D, data, null, qualityGateStatus, variation);
}
public Measure create(boolean value) {
*/
public boolean getBooleanValue() {
checkValueType(ValueType.BOOLEAN);
- return value == 1.0d;
+ return value == 1.0D;
}
/**
// the actual value in the QG failure reason
result.addProperty("period", 1);
}
- if (condition.getWarningThreshold() != null) {
- result.addProperty("warning", condition.getWarningThreshold());
- }
- if (condition.getErrorThreshold() != null) {
- result.addProperty("error", condition.getErrorThreshold());
- }
+ result.addProperty("error", condition.getErrorThreshold());
result.addProperty("actual", evaluatedCondition.getActualValue());
result.addProperty(FIELD_LEVEL, evaluatedCondition.getLevel().name());
return result;
package org.sonar.ce.task.projectanalysis.qualitygate;
import com.google.common.base.MoreObjects;
-import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.sonar.ce.task.projectanalysis.metric.Metric;
private final Metric metric;
private final Operator operator;
- @CheckForNull
- private final String warningThreshold;
- @CheckForNull
private final String errorThreshold;
private final boolean useVariation;
- public Condition(Metric metric, String operator,
- @Nullable String errorThreshold, @Nullable String warningThreshold) {
+ public Condition(Metric metric, String operator, String errorThreshold) {
this.metric = requireNonNull(metric);
this.operator = parseFromDbValue(requireNonNull(operator));
this.useVariation = metric.getKey().startsWith("new_");
this.errorThreshold = errorThreshold;
- this.warningThreshold = warningThreshold;
}
private static Operator parseFromDbValue(String str) {
return operator;
}
- @CheckForNull
- public String getWarningThreshold() {
- return warningThreshold;
- }
-
- @CheckForNull
public String getErrorThreshold() {
return errorThreshold;
}
return MoreObjects.toStringHelper(this)
.add("metric", metric)
.add("operator", operator)
- .add("warningThreshold", warningThreshold)
.add("errorThreshold", errorThreshold)
.toString();
}
import java.util.Optional;
import javax.annotation.CheckForNull;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.ce.task.projectanalysis.metric.Metric;
import org.sonar.ce.task.projectanalysis.measure.Measure;
+import org.sonar.ce.task.projectanalysis.metric.Metric;
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Optional.of;
return new EvaluationResult(Measure.Level.OK, null);
}
- return evaluateCondition(condition, measureComparable, Measure.Level.ERROR)
- .orElseGet(() -> evaluateCondition(condition, measureComparable, Measure.Level.WARN)
- .orElseGet(() -> new EvaluationResult(Measure.Level.OK, measureComparable)));
+ return evaluateCondition(condition, measureComparable)
+ .orElseGet(() -> new EvaluationResult(Measure.Level.OK, measureComparable));
}
- private static Optional<EvaluationResult> evaluateCondition(Condition condition, Comparable<?> measureComparable, Measure.Level alertLevel) {
- String conditionValue = getValueToEval(condition, alertLevel);
- if (StringUtils.isEmpty(conditionValue)) {
- return Optional.empty();
- }
-
+ private static Optional<EvaluationResult> evaluateCondition(Condition condition, Comparable<?> measureComparable) {
try {
- Comparable conditionComparable = parseConditionValue(condition.getMetric(), conditionValue);
+ Comparable conditionComparable = parseConditionValue(condition.getMetric(), condition.getErrorThreshold());
if (doesReachThresholds(measureComparable, conditionComparable, condition)) {
- return of(new EvaluationResult(alertLevel, measureComparable));
+ return of(new EvaluationResult(Measure.Level.ERROR, measureComparable));
}
return Optional.empty();
} catch (NumberFormatException badValueFormat) {
throw new IllegalArgumentException(String.format(
"Quality Gate: Unable to parse value '%s' to compare against %s",
- conditionValue, condition.getMetric().getName()));
- }
- }
-
- private static String getValueToEval(Condition condition, Measure.Level alertLevel) {
- if (Measure.Level.ERROR.equals(alertLevel)) {
- return condition.getErrorThreshold();
- } else if (Measure.Level.WARN.equals(alertLevel)) {
- return condition.getWarningThreshold();
- } else {
- throw new IllegalStateException(alertLevel.toString());
+ condition.getErrorThreshold(), condition.getMetric().getName()));
}
}
}
public enum EvaluationStatus {
- NO_VALUE, OK, WARN, ERROR
+ NO_VALUE, OK, ERROR
}
}
import org.sonar.ce.task.projectanalysis.metric.Metric;
import static java.util.Objects.requireNonNull;
-import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.ERROR;
public final class EvaluationResultTextConverterImpl implements EvaluationResultTextConverter {
private static final Map<Condition.Operator, String> OPERATOR_LABELS = ImmutableMap.of(
if (evaluationResult.getLevel() == Measure.Level.OK) {
return null;
}
- return getAlertLabel(condition, evaluationResult.getLevel());
+ return getAlertLabel(condition);
}
- private String getAlertLabel(Condition condition, Measure.Level level) {
+ private String getAlertLabel(Condition condition) {
String metric = i18n.message(Locale.ENGLISH, "metric." + condition.getMetric().getKey() + ".name", condition.getMetric().getName());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder
.append(" ").append(OPERATOR_LABELS.get(condition.getOperator())).append(" ")
- .append(alertValue(condition, level));
+ .append(alertValue(condition));
return stringBuilder.toString();
}
- private String alertValue(Condition condition, Measure.Level level) {
- String value = level == ERROR ? condition.getErrorThreshold() : condition.getWarningThreshold();
+ private String alertValue(Condition condition) {
if (condition.getMetric().getType() == Metric.MetricType.WORK_DUR) {
- return formatDuration(value);
+ return formatDuration(condition.getErrorThreshold());
}
- return value;
+ return condition.getErrorThreshold();
}
private String formatDuration(String value) {
Iterable<Condition> conditions = dtos.stream()
.map(input -> metricRepository.getOptionalById(input.getMetricId())
- .map(metric -> new Condition(metric, input.getOperator(), input.getErrorThreshold(), input.getWarningThreshold()))
+ .map(metric -> new Condition(metric, input.getOperator(), input.getErrorThreshold()))
.orElse(null))
.filter(Objects::nonNull)
.collect(toList(dtos.size()));
ShortLivingBranchQualityGate.ID,
ShortLivingBranchQualityGate.NAME,
ShortLivingBranchQualityGate.CONDITIONS.stream()
- .map(c -> new Condition(metricRepository.getByKey(c.getMetricKey()), c.getOperator(), c.getErrorThreshold(), c.getWarnThreshold()))
+ .map(c -> new Condition(metricRepository.getByKey(c.getMetricKey()), c.getOperator(), c.getErrorThreshold()))
.collect(toList(ShortLivingBranchQualityGate.CONDITIONS.size())));
}
package org.sonar.ce.task.projectanalysis.qualitygate;
public enum QualityGateStatus {
- OK, WARN, ERROR
+ OK, ERROR
}
}
/**
- * @param label "Red (was Orange)"
- * @param rawStatus OK, WARN or ERROR + optional text
+ * @param label "Red (was Green)"
+ * @param rawStatus OK or ERROR + optional text
*/
private void notifyUsers(Component project, String label, QualityGateStatus rawStatus, boolean isNewAlert) {
Notification notification = new Notification("alerts")
switch (globalLevel) {
case OK:
return ConditionStatus.EvaluationStatus.OK;
- case WARN:
- return ConditionStatus.EvaluationStatus.WARN;
case ERROR:
return ConditionStatus.EvaluationStatus.ERROR;
default:
switch (globalLevel) {
case OK:
return org.sonar.ce.task.projectanalysis.qualitygate.QualityGateStatus.OK;
- case WARN:
- return org.sonar.ce.task.projectanalysis.qualitygate.QualityGateStatus.WARN;
case ERROR:
return org.sonar.ce.task.projectanalysis.qualitygate.QualityGateStatus.ERROR;
default:
public void addEvaluatedCondition(MetricEvaluationResult metricEvaluationResult) {
Measure.Level level = metricEvaluationResult.evaluationResult.getLevel();
- if (Measure.Level.WARN == level && this.globalLevel != Measure.Level.ERROR) {
- globalLevel = Measure.Level.WARN;
-
- } else if (Measure.Level.ERROR == level) {
+ if (Measure.Level.ERROR == level) {
globalLevel = Measure.Level.ERROR;
}
evaluatedConditions.add(
EvaluatedQualityGate.Builder builder = EvaluatedQualityGate.newBuilder();
Set<Condition> conditions = qg.getConditions().stream()
.map(q -> {
- Condition condition = new Condition(q.getMetricKey(), Condition.Operator.valueOf(q.getOperator().name()),
- q.getErrorThreshold(), q.getWarningThreshold());
+ Condition condition = new Condition(q.getMetricKey(), Condition.Operator.valueOf(q.getOperator().name()), q.getErrorThreshold());
builder.addCondition(condition,
EvaluatedCondition.EvaluationStatus.valueOf(q.getStatus().name()),
q.getStatus() == org.sonar.api.ce.posttask.QualityGate.EvaluationStatus.NO_VALUE ? null : q.getValue());
public class ConditionImplTest {
private static final String METRIC_KEY = "metricKey";
private static final String ERROR_THRESHOLD = "error threshold";
- private static final String WARN_THRESHOLD = "warn threshold";
private static final String VALUE = "value";
@Rule
.setMetricKey(METRIC_KEY)
.setOperator(QualityGate.Operator.GREATER_THAN)
.setErrorThreshold(ERROR_THRESHOLD)
- .setWarningThreshold(WARN_THRESHOLD)
.setValue(VALUE);
@Test
}
@Test
- public void build_throws_IAE_if_both_thresholds_are_null() {
- builder.setWarningThreshold(null)
- .setErrorThreshold(null);
+ public void build_throws_NPE_if_error_threshold_is_null() {
+ builder.setErrorThreshold(null);
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("At least one of errorThreshold and warningThreshold must be non null");
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("errorThreshold can not be null");
builder.build();
}
public void toString_ConditionImpl_of_type_different_from_NO_VALUE() {
assertThat(builder.build().toString())
.isEqualTo(
- "ConditionImpl{status=OK, metricKey='metricKey', operator=GREATER_THAN, errorThreshold='error threshold', warningThreshold='warn threshold', value='value'}");
+ "ConditionImpl{status=OK, metricKey='metricKey', operator=GREATER_THAN, errorThreshold='error threshold', value='value'}");
}
@Test
assertThat(builder.build().toString())
.isEqualTo(
- "ConditionImpl{status=NO_VALUE, metricKey='metricKey', operator=GREATER_THAN, errorThreshold='error threshold', warningThreshold='warn threshold', value='null'}");
+ "ConditionImpl{status=NO_VALUE, metricKey='metricKey', operator=GREATER_THAN, errorThreshold='error threshold', value='null'}");
}
@Test
assertThat(underTest.getMetricKey()).isEqualTo(METRIC_KEY);
assertThat(underTest.getOperator()).isEqualTo(QualityGate.Operator.GREATER_THAN);
assertThat(underTest.getErrorThreshold()).isEqualTo(ERROR_THRESHOLD);
- assertThat(underTest.getWarningThreshold()).isEqualTo(WARN_THRESHOLD);
assertThat(underTest.getValue()).isEqualTo(VALUE);
}
}
public class ConditionToConditionTest {
private static final String METRIC_KEY = "metricKey";
private static final String ERROR_THRESHOLD = "error threshold";
- private static final String WARN_THRESHOLD = "warn threshold";
private static final Map<Condition, ConditionStatus> NO_STATUS_PER_CONDITIONS = Collections.emptyMap();
private static final String SOME_VALUE = "some value";
private static final ConditionStatus SOME_CONDITION_STATUS = ConditionStatus.create(ConditionStatus.EvaluationStatus.OK, SOME_VALUE);
- private static final Condition SOME_CONDITION = new Condition(newMetric(METRIC_KEY), Condition.Operator.EQUALS.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD);
-
+ private static final Condition SOME_CONDITION = new Condition(newMetric(METRIC_KEY), Condition.Operator.EQUALS.getDbValue(), ERROR_THRESHOLD);
@Rule
public ExpectedException expectedException = ExpectedException.none();
ConditionToCondition underTest = new ConditionToCondition(of(SOME_CONDITION, SOME_CONDITION_STATUS));
assertThat(underTest.apply(SOME_CONDITION).getErrorThreshold()).isEqualTo(ERROR_THRESHOLD);
- assertThat(underTest.apply(SOME_CONDITION).getWarningThreshold()).isEqualTo(WARN_THRESHOLD);
}
@Test
@UseDataProvider("allOperatorValues")
public void apply_converts_all_values_of_operator(Condition.Operator operator) {
- Condition condition = new Condition(newMetric(METRIC_KEY), operator.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD);
+ Condition condition = new Condition(newMetric(METRIC_KEY), operator.getDbValue(), ERROR_THRESHOLD);
ConditionToCondition underTest = new ConditionToCondition(of(condition, SOME_CONDITION_STATUS));
assertThat(underTest.apply(condition).getOperator().name()).isEqualTo(operator.name());
@Test
public void apply_copies_value() {
- Condition otherCondition = new Condition(newMetric(METRIC_KEY), Condition.Operator.NOT_EQUALS.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD);
+ Condition otherCondition = new Condition(newMetric(METRIC_KEY), Condition.Operator.NOT_EQUALS.getDbValue(), ERROR_THRESHOLD);
ConditionToCondition underTest = new ConditionToCondition(of(
SOME_CONDITION, SOME_CONDITION_STATUS,
otherCondition, ConditionStatus.NO_VALUE_STATUS));
private static Condition createCondition(String metricKey) {
Metric metric = mock(Metric.class);
when(metric.getKey()).thenReturn(metricKey);
- return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), "error threshold", "warn threshold");
+ return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), "error threshold");
}
}
static {
when(SOME_METRIC.getKey()).thenReturn("dummy key");
}
- private static final Condition SOME_CONDITION = new Condition(SOME_METRIC, Condition.Operator.EQUALS.getDbValue(), "1", null);
+ private static final Condition SOME_CONDITION = new Condition(SOME_METRIC, Condition.Operator.EQUALS.getDbValue(), "1");
private static final Measure.Level SOME_LEVEL = Measure.Level.OK;
private static final String SOME_VALUE = "some value";
@Test
public void verify_json_for_each_type_of_condition() {
String value = "actualValue";
- Condition condition = new Condition(new MetricImpl(1, "key1", "name1", Metric.MetricType.STRING), Condition.Operator.GREATER_THAN.getDbValue(), "errorTh", "warnTh");
+ Condition condition = new Condition(new MetricImpl(1, "key1", "name1", Metric.MetricType.STRING), Condition.Operator.GREATER_THAN.getDbValue(), "errorTh");
ImmutableList<EvaluatedCondition> evaluatedConditions = ImmutableList.of(
new EvaluatedCondition(condition, Measure.Level.OK, value),
- new EvaluatedCondition(condition, Measure.Level.WARN, value),
new EvaluatedCondition(condition, Measure.Level.ERROR, value));
String actualJson = new QualityGateDetailsData(Measure.Level.OK, evaluatedConditions, false).toJson();
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
- " \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
" \"level\":\"OK\"" +
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
- " \"warning\":\"warnTh\"," +
- " \"error\":\"errorTh\"," +
- " \"actual\":\"actualValue\"," +
- " \"level\":\"WARN\"" +
- " }," +
- " {" +
- " \"metric\":\"key1\"," +
- " \"op\":\"GT\"," +
- " \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
" \"level\":\"ERROR\"" +
}
@Test
- public void testErrorAndWarningLevel() {
+ public void testErrorLevel() {
Metric metric = createMetric(FLOAT);
Measure measure = newMeasureBuilder().create(10.2d, 1, null);
assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), measure)).hasLevel(ERROR);
assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.1"), measure)).hasLevel(OK);
- assertThat(underTest.evaluate(new Condition(metric, EQUALS.getDbValue(), "10.3", "10.2"), measure)).hasLevel(Measure.Level.WARN);
- assertThat(underTest.evaluate(new Condition(metric, LESS_THAN.getDbValue(), "10.3", "10.2"), measure)).hasLevel(Measure.Level.ERROR);
+ assertThat(underTest.evaluate(new Condition(metric, EQUALS.getDbValue(), "10.3"), measure)).hasLevel(Measure.Level.OK);
+ assertThat(underTest.evaluate(new Condition(metric, LESS_THAN.getDbValue(), "10.3"), measure)).hasLevel(Measure.Level.ERROR);
}
@Test
Metric metric = createNewMetric(metricType);
Measure measure = newMeasureBuilder().setVariation(3d).createNoValue();
- assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null), measure)).hasLevel(OK);
- assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "2", null), measure)).hasLevel(ERROR);
+ assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3"), measure)).hasLevel(OK);
+ assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "2"), measure)).hasLevel(ERROR);
}
@Test
Metric metric = createNewMetric(metricType);
Measure measure = newMeasureBuilder().createNoValue();
- assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null), measure)).hasLevel(OK).hasValue(null);
+ assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3"), measure)).hasLevel(OK).hasValue(null);
}
@DataProvider
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Unsupported metric type " + metricType);
- underTest.evaluate(new Condition(metric, EQUALS.getDbValue(), "3", null), measure);
+ underTest.evaluate(new Condition(metric, EQUALS.getDbValue(), "3"), measure);
}
@DataProvider
Metric metric = createMetric(RATING);
Measure measure = newMeasureBuilder().create(4, "D");
- assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "4", null), measure)).hasLevel(OK).hasValue(4);
- assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "2", null), measure)).hasLevel(ERROR).hasValue(4);
+ assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "4"), measure)).hasLevel(OK).hasValue(4);
+ assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "2"), measure)).hasLevel(ERROR).hasValue(4);
}
private static Condition createErrorCondition(Metric metric, Condition.Operator operator, String errorThreshold) {
- return new Condition(metric, operator.getDbValue(), errorThreshold, null);
+ return new Condition(metric, operator.getDbValue(), errorThreshold);
}
private static MetricImpl createMetric(MetricType metricType) {
@Test(expected = NullPointerException.class)
public void constructor_throws_NPE_for_null_metric_argument() {
- new Condition(null, SOME_OPERATOR, null, null);
+ new Condition(null, SOME_OPERATOR, null);
}
@Test(expected = NullPointerException.class)
public void constructor_throws_NPE_for_null_operator_argument() {
- new Condition(SOME_METRIC, null, null, null);
+ new Condition(SOME_METRIC, null, null);
}
@Test
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Unsupported operator value: 'troloto'");
- new Condition(SOME_METRIC, "troloto", null, null);
+ new Condition(SOME_METRIC, "troloto", null);
}
@Test
public void verify_getters() {
String error = "error threshold";
- String warning = "warning threshold";
- Condition condition = new Condition(SOME_METRIC, SOME_OPERATOR, error, warning);
+ Condition condition = new Condition(SOME_METRIC, SOME_OPERATOR, error);
assertThat(condition.getMetric()).isSameAs(SOME_METRIC);
assertThat(condition.getOperator()).isSameAs(Condition.Operator.EQUALS);
assertThat(condition.getErrorThreshold()).isEqualTo(error);
- assertThat(condition.getWarningThreshold()).isEqualTo(warning);
}
@Test
public void all_fields_are_displayed_in_toString() {
when(SOME_METRIC.toString()).thenReturn("metric1");
- assertThat(new Condition(SOME_METRIC, SOME_OPERATOR, "error_l", "warn").toString())
- .isEqualTo("Condition{metric=metric1, operator=EQUALS, warningThreshold=warn, errorThreshold=error_l}");
+ assertThat(new Condition(SOME_METRIC, SOME_OPERATOR, "error_l").toString())
+ .isEqualTo("Condition{metric=metric1, operator=EQUALS, errorThreshold=error_l}");
+
}
}
*/
package org.sonar.ce.task.projectanalysis.qualitygate;
-import com.google.common.collect.ImmutableList;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.ERROR;
-import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.WARN;
@RunWith(DataProviderRunner.class)
public class EvaluationResultTextConverterTest {
private static final Metric INT_METRIC = new MetricImpl(1, "key", "int_metric_name", Metric.MetricType.INT);
private static final Metric SOME_VARIATION_METRIC = new MetricImpl(2, "new_variation_of_trololo", "variation_of_trololo_name", Metric.MetricType.INT);
- private static final Condition EQ_10_CONDITION = new Condition(INT_METRIC, Condition.Operator.EQUALS.getDbValue(), "10", null);
+ private static final Condition EQ_10_CONDITION = new Condition(INT_METRIC, Condition.Operator.EQUALS.getDbValue(), "10");
private static final EvaluationResult OK_EVALUATION_RESULT = new EvaluationResult(Measure.Level.OK, null);
private static final String ERROR_THRESHOLD = "error_threshold";
- private static final String WARNING_THRESHOLD = "warning_threshold";
- private static final String SOME_MODE = "mode";
- private static final String SOME_ANALYSIS_UUID = "u1";
private I18n i18n = mock(I18n.class);
private Durations durations = mock(Durations.class);
}
@DataProvider
- public static Object[][] all_operators_for_error_warning_levels() {
+ public static Object[][] all_operators_for_error_levels() {
List<Object[]> res = new ArrayList<>();
for (Condition.Operator operator : Condition.Operator.values()) {
- for (Measure.Level level : ImmutableList.of(ERROR, WARN)) {
- res.add(new Object[] {operator, level});
- }
+ res.add(new Object[] {operator, ERROR});
}
return res.toArray(new Object[res.size()][2]);
}
@Test
- @UseDataProvider("all_operators_for_error_warning_levels")
+ @UseDataProvider("all_operators_for_error_levels")
public void evaluate_returns_msg_of_metric_plus_operator_plus_threshold_for_level_argument(Condition.Operator operator, Measure.Level level) {
String metricMsg = "int_metric_msg";
when(i18n.message(Locale.ENGLISH, "metric." + INT_METRIC.getKey() + ".name", INT_METRIC.getName()))
.thenReturn(metricMsg);
- Condition condition = new Condition(INT_METRIC, operator.getDbValue(), ERROR_THRESHOLD, WARNING_THRESHOLD);
+ Condition condition = new Condition(INT_METRIC, operator.getDbValue(), ERROR_THRESHOLD);
assertThat(underTest.asText(condition, new EvaluationResult(level, null)))
- .isEqualTo(metricMsg + " " + toSign(operator) + " " + getThreshold(level));
- }
-
- private String getThreshold(Measure.Level level) {
- return level == ERROR ? ERROR_THRESHOLD : WARNING_THRESHOLD;
+ .isEqualTo(metricMsg + " " + toSign(operator) + " " + ERROR_THRESHOLD);
}
@Test
- @UseDataProvider("all_operators_for_error_warning_levels")
+ @UseDataProvider("all_operators_for_error_levels")
public void evaluate_does_not_add_variation_if_metric_starts_with_variation_prefix_but_period_is_null(Condition.Operator operator, Measure.Level level) {
String metricMsg = "trololo_metric_msg";
when(i18n.message(Locale.ENGLISH, "metric." + SOME_VARIATION_METRIC.getKey() + ".name", SOME_VARIATION_METRIC.getName()))
.thenReturn(metricMsg);
- Condition condition = new Condition(SOME_VARIATION_METRIC, operator.getDbValue(), ERROR_THRESHOLD, WARNING_THRESHOLD);
+ Condition condition = new Condition(SOME_VARIATION_METRIC, operator.getDbValue(), ERROR_THRESHOLD);
assertThat(underTest.asText(condition, new EvaluationResult(level, null)))
- .isEqualTo(metricMsg + " " + toSign(operator) + " " + getThreshold(level));
+ .isEqualTo(metricMsg + " " + toSign(operator) + " " + ERROR_THRESHOLD);
}
private static String toSign(Condition.Operator operator) {
private static final Metric METRIC_1 = mock(Metric.class);
private static final Metric METRIC_2 = mock(Metric.class);
private static final QualityGateConditionDto CONDITION_1 = new QualityGateConditionDto().setId(321).setMetricId(METRIC_ID_1).setOperator("EQ")
- .setWarningThreshold("warnin_th").setErrorThreshold("error_th");
- private static final QualityGateConditionDto CONDITION_2 = new QualityGateConditionDto().setId(456).setMetricId(METRIC_ID_2).setOperator("NE");
+ .setErrorThreshold("error_th");
+ private static final QualityGateConditionDto CONDITION_2 = new QualityGateConditionDto().setId(456).setMetricId(METRIC_ID_2).setOperator("NE").setErrorThreshold("error_th");
private QualityGateDao qualityGateDao = mock(QualityGateDao.class);
private QualityGateConditionDao qualityGateConditionDao = mock(QualityGateConditionDao.class);
assertThat(res.get().getId()).isEqualTo(SOME_ID);
assertThat(res.get().getName()).isEqualTo(SOME_NAME);
assertThat(res.get().getConditions()).containsOnly(
- new Condition(METRIC_1, CONDITION_1.getOperator(), CONDITION_1.getErrorThreshold(), CONDITION_1.getWarningThreshold()),
- new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold(), CONDITION_2.getWarningThreshold()));
+ new Condition(METRIC_1, CONDITION_1.getOperator(), CONDITION_1.getErrorThreshold()),
+ new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold()));
}
@Test
assertThat(res.get().getId()).isEqualTo(SOME_ID);
assertThat(res.get().getName()).isEqualTo(SOME_NAME);
assertThat(res.get().getConditions()).containsOnly(
- new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold(), CONDITION_2.getWarningThreshold()));
+ new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold()));
}
@Test
assertThat(qualityGate.getId()).isEqualTo(ShortLivingBranchQualityGate.ID);
assertThat(qualityGate.getName()).isEqualTo("Hardcoded short living branch quality gate");
assertThat(qualityGate.getConditions())
- .extracting(Condition::getMetric, Condition::getOperator, Condition::getErrorThreshold, Condition::getWarningThreshold)
+ .extracting(Condition::getMetric, Condition::getOperator, Condition::getErrorThreshold)
.containsOnly(
- tuple(openedIssueMetric, GREATER_THAN, "0", null),
- tuple(reOpenedIssueMetric, GREATER_THAN, "0", null));
+ tuple(openedIssueMetric, GREATER_THAN, "0"),
+ tuple(reOpenedIssueMetric, GREATER_THAN, "0"));
}
private MetricImpl mockMetricInRepository(String metricKey) {
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.ERROR;
import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.OK;
-import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.WARN;
public class QualityGateEventsStepTest {
private static final ReportComponent PROJECT_COMPONENT = ReportComponent.builder(Component.Type.PROJECT, 1)
private static final String INVALID_ALERT_STATUS = "trololo";
private static final String ALERT_TEXT = "alert text";
private static final QualityGateStatus OK_QUALITY_GATE_STATUS = new QualityGateStatus(OK, ALERT_TEXT);
- private static final QualityGateStatus WARN_QUALITY_GATE_STATUS = new QualityGateStatus(WARN, ALERT_TEXT);
private static final QualityGateStatus ERROR_QUALITY_GATE_STATUS = new QualityGateStatus(ERROR, ALERT_TEXT);
@Rule
verifyNoMoreInteractions(measureRepository, eventRepository);
}
- @Test
- public void event_created_if_no_base_ALERT_STATUS_and_raw_is_WARN() {
- verify_event_created_if_no_base_ALERT_STATUS_measure(WARN, "Orange");
- }
-
- @Test
- public void event_created_if_base_ALERT_STATUS_and_raw_is_ERROR() {
- verify_event_created_if_no_base_ALERT_STATUS_measure(ERROR, "Red");
- }
-
@Test
public void event_created_if_base_ALERT_STATUS_has_no_alertStatus_and_raw_is_ERROR() {
verify_event_created_if_no_base_ALERT_STATUS_measure(ERROR, "Red");
}
- @Test
- public void event_created_if_base_ALERT_STATUS_has_no_alertStatus_and_raw_is_WARN() {
- verify_event_created_if_no_base_ALERT_STATUS_measure(WARN, "Orange");
- }
-
@Test
public void event_created_if_base_ALERT_STATUS_has_invalid_alertStatus_and_raw_is_ERROR() {
verify_event_created_if_no_base_ALERT_STATUS_measure(ERROR, "Red");
}
- @Test
- public void event_created_if_base_ALERT_STATUS_has_invalid_alertStatus_and_raw_is_WARN() {
- verify_event_created_if_no_base_ALERT_STATUS_measure(WARN, "Orange");
- }
-
private void verify_event_created_if_no_base_ALERT_STATUS_measure(Measure.Level rawAlterStatus, String expectedLabel) {
QualityGateStatus someQGStatus = new QualityGateStatus(rawAlterStatus, ALERT_TEXT);
@Test
public void event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed() {
- verify_event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed(OK, WARN_QUALITY_GATE_STATUS, "Orange (was Green)");
verify_event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed(OK, ERROR_QUALITY_GATE_STATUS, "Red (was Green)");
- verify_event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed(WARN, OK_QUALITY_GATE_STATUS, "Green (was Orange)");
- verify_event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed(WARN, ERROR_QUALITY_GATE_STATUS, "Red (was Orange)");
verify_event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed(ERROR, OK_QUALITY_GATE_STATUS, "Green (was Red)");
- verify_event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed(ERROR, WARN_QUALITY_GATE_STATUS, "Orange (was Red)");
}
private void verify_event_created_if_base_ALERT_STATUS_measure_exists_and_status_has_changed(Measure.Level previousAlertStatus,
});
when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric))
- .thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(WARN_QUALITY_GATE_STATUS).createNoValue()));
+ .thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(OK_QUALITY_GATE_STATUS).createNoValue()));
when(measureRepository.getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(
of(Measure.newMeasureBuilder().setQualityGateStatus(new QualityGateStatus(ERROR)).createNoValue()));
analysisMetadataHolder.setBranch(new DefaultBranchImpl());
when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric))
- .thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(WARN_QUALITY_GATE_STATUS).createNoValue()));
+ .thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(OK_QUALITY_GATE_STATUS).createNoValue()));
when(measureRepository.getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(
of(Measure.newMeasureBuilder().setQualityGateStatus(new QualityGateStatus(ERROR)).createNoValue()));
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import javax.annotation.Nullable;
import org.assertj.core.api.AbstractAssert;
import org.junit.Before;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
-import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.ERROR;
import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.OK;
-import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.WARN;
+import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
import static org.sonar.ce.task.projectanalysis.measure.MeasureAssert.assertThat;
public class QualityGateMeasuresStepTest {
@Test
public void new_measures_are_created_even_if_there_is_no_rawMeasure_for_metric_of_condition() {
- Condition equals2Condition = createEqualsCondition(INT_METRIC_1, "2", null);
+ Condition equals2Condition = createEqualsCondition(INT_METRIC_1, "2");
qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(equals2Condition)));
underTest.execute(new TestComputationStepContext());
@Test
public void rawMeasure_is_updated_if_present_and_new_measures_are_created_if_project_has_measure_for_metric_of_condition() {
int rawValue = 1;
- Condition equals2Condition = createEqualsCondition(INT_METRIC_1, "2", null);
+ Condition equals2Condition = createEqualsCondition(INT_METRIC_1, "2");
Measure rawMeasure = newMeasureBuilder().create(rawValue, null);
qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(equals2Condition)));
@Test
public void new_measures_have_ERROR_level_if_at_least_one_updated_measure_has_ERROR_level() {
int rawValue = 1;
- Condition equals1ErrorCondition = createEqualsCondition(INT_METRIC_1, "1", null);
- Condition equals1WarningCondition = createEqualsCondition(INT_METRIC_2, null, "1");
+ Condition equalsOneErrorCondition = createEqualsCondition(INT_METRIC_1, "1");
+ Condition equalsOneOkCondition = createEqualsCondition(INT_METRIC_2, "2");
Measure rawMeasure = newMeasureBuilder().create(rawValue, null);
- qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(equals1ErrorCondition, equals1WarningCondition)));
+ qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(equalsOneErrorCondition, equalsOneOkCondition)));
measureRepository.addRawMeasure(PROJECT_REF, INT_METRIC_1_KEY, rawMeasure);
measureRepository.addRawMeasure(PROJECT_REF, INT_METRIC_2_KEY, rawMeasure);
assertThat(rawMeasure1.get())
.hasQualityGateLevel(ERROR)
- .hasQualityGateText(dumbResultTextAnswer(equals1ErrorCondition, ERROR, rawValue));
+ .hasQualityGateText(dumbResultTextAnswer(equalsOneErrorCondition, ERROR, rawValue));
assertThat(rawMeasure2.get())
- .hasQualityGateLevel(WARN)
- .hasQualityGateText(dumbResultTextAnswer(equals1WarningCondition, WARN, rawValue));
+ .hasQualityGateLevel(OK)
+ .hasQualityGateText(dumbResultTextAnswer(equalsOneOkCondition, OK, rawValue));
assertThat(getAlertStatusMeasure())
.hasQualityGateLevel(ERROR)
- .hasQualityGateText(dumbResultTextAnswer(equals1ErrorCondition, ERROR, rawValue) + ", "
- + dumbResultTextAnswer(equals1WarningCondition, WARN, rawValue));
+ .hasQualityGateText(dumbResultTextAnswer(equalsOneErrorCondition, ERROR, rawValue) + ", "
+ + dumbResultTextAnswer(equalsOneOkCondition, OK, rawValue));
assertThat(getQGDetailsMeasure())
.hasValue(new QualityGateDetailsData(ERROR, of(
- new EvaluatedCondition(equals1ErrorCondition, ERROR, rawValue),
- new EvaluatedCondition(equals1WarningCondition, WARN, rawValue)), false).toJson());
+ new EvaluatedCondition(equalsOneErrorCondition, ERROR, rawValue),
+ new EvaluatedCondition(equalsOneOkCondition, OK, rawValue)), false).toJson());
QualityGateStatusHolderAssertions.assertThat(qualityGateStatusHolder)
.hasStatus(QualityGateStatus.ERROR)
.hasConditionCount(2)
- .hasCondition(equals1ErrorCondition, ConditionStatus.EvaluationStatus.ERROR, String.valueOf(rawValue))
- .hasCondition(equals1WarningCondition, ConditionStatus.EvaluationStatus.WARN, String.valueOf(rawValue));
- }
-
- @Test
- public void new_measures_have_WARNING_level_if_no_updated_measure_has_ERROR_level() {
- int rawValue = 1;
- Condition equals2Condition = createEqualsCondition(INT_METRIC_1, "2", null);
- Condition equals1WarningCondition = createEqualsCondition(INT_METRIC_2, null, "1");
- Measure rawMeasure = newMeasureBuilder().create(rawValue, null);
-
- qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(equals2Condition, equals1WarningCondition)));
- measureRepository.addRawMeasure(PROJECT_REF, INT_METRIC_1_KEY, rawMeasure);
- measureRepository.addRawMeasure(PROJECT_REF, INT_METRIC_2_KEY, rawMeasure);
-
- underTest.execute(new TestComputationStepContext());
-
- Optional<Measure> rawMeasure1 = measureRepository.getAddedRawMeasure(PROJECT_REF, INT_METRIC_1_KEY);
- Optional<Measure> rawMeasure2 = measureRepository.getAddedRawMeasure(PROJECT_REF, INT_METRIC_2_KEY);
-
- assertThat(rawMeasure1.get())
- .hasQualityGateLevel(OK)
- .hasQualityGateText(dumbResultTextAnswer(equals2Condition, OK, rawValue));
- assertThat(rawMeasure2.get())
- .hasQualityGateLevel(WARN)
- .hasQualityGateText(dumbResultTextAnswer(equals1WarningCondition, WARN, rawValue));
- assertThat(getAlertStatusMeasure())
- .hasQualityGateLevel(WARN)
- .hasQualityGateText(dumbResultTextAnswer(equals2Condition, OK, rawValue) + ", "
- + dumbResultTextAnswer(equals1WarningCondition, WARN, rawValue));
- assertThat(getQGDetailsMeasure())
- .hasValue(new QualityGateDetailsData(WARN, of(
- new EvaluatedCondition(equals2Condition, OK, rawValue),
- new EvaluatedCondition(equals1WarningCondition, WARN, rawValue)), false).toJson());
-
- QualityGateStatusHolderAssertions.assertThat(qualityGateStatusHolder)
- .hasStatus(QualityGateStatus.WARN)
- .hasConditionCount(2)
- .hasCondition(equals2Condition, ConditionStatus.EvaluationStatus.OK, String.valueOf(rawValue))
- .hasCondition(equals1WarningCondition, ConditionStatus.EvaluationStatus.WARN, String.valueOf(rawValue));
+ .hasCondition(equalsOneErrorCondition, ConditionStatus.EvaluationStatus.ERROR, String.valueOf(rawValue))
+ .hasCondition(equalsOneOkCondition, ConditionStatus.EvaluationStatus.OK, String.valueOf(rawValue));
}
@Test
public void new_measure_has_ERROR_level_of_all_conditions_for_a_specific_metric_if_its_the_worst() {
int rawValue = 1;
- Condition fixedCondition = createEqualsCondition(INT_METRIC_1, "1", null);
- Condition periodCondition = createEqualsCondition(INT_METRIC_1, null, "2");
+ Condition fixedCondition = createEqualsCondition(INT_METRIC_1, "1");
+ Condition periodCondition = createEqualsCondition(INT_METRIC_1, "2");
qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(fixedCondition, periodCondition)));
Measure measure = newMeasureBuilder().create(rawValue, null);
@Test
public void new_measure_has_condition_on_leak_period_when_all_conditions_on_specific_metric_has_same_QG_level() {
int rawValue = 1;
- Condition fixedCondition = createEqualsCondition(INT_METRIC_1, "1", null);
- Condition periodCondition = createEqualsCondition(INT_METRIC_1, "1", null);
+ Condition fixedCondition = createEqualsCondition(INT_METRIC_1, "1");
+ Condition periodCondition = createEqualsCondition(INT_METRIC_1, "1");
qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(fixedCondition, periodCondition)));
Measure measure = newMeasureBuilder()
return measureRepository.getAddedRawMeasure(PROJECT_REF, CoreMetrics.QUALITY_GATE_DETAILS_KEY);
}
- private static Condition createEqualsCondition(Metric metric, @Nullable String errorThreshold, @Nullable String warningThreshold) {
- return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), errorThreshold, warningThreshold);
+ private static Condition createEqualsCondition(Metric metric, String errorThreshold) {
+ return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), errorThreshold);
}
private static MetricImpl createIntMetric(int index) {
import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.ERROR;
import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.OK;
-import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.WARN;
public class SmallChangesetQualityGateSpecialCaseTest {
assertThat(result).isTrue();
}
- @Test
- public void ignore_warnings_about_new_coverage_for_small_changesets() {
- QualityGateMeasuresStep.MetricEvaluationResult metricEvaluationResult = generateEvaluationResult(NEW_COVERAGE_KEY, WARN);
- Component project = generateNewRootProject();
- measureRepository.addRawMeasure(PROJECT_REF, CoreMetrics.NEW_LINES_KEY, newMeasureBuilder().setVariation(19).create(1000));
-
- boolean result = underTest.appliesTo(project, metricEvaluationResult);
-
- assertThat(result).isTrue();
- }
-
@Test
public void should_not_change_for_bigger_changesets() {
QualityGateMeasuresStep.MetricEvaluationResult metricEvaluationResult = generateEvaluationResult(NEW_COVERAGE_KEY, ERROR);
private QualityGateMeasuresStep.MetricEvaluationResult generateEvaluationResult(String metric, Measure.Level level) {
Metric newCoverageMetric = metricRepository.getByKey(metric);
- Condition condition = new Condition(newCoverageMetric, "LT", "80", "90");
+ Condition condition = new Condition(newCoverageMetric, "LT", "80");
EvaluationResult evaluationResult = new EvaluationResult(level, mock(Comparable.class));
return new QualityGateMeasuresStep.MetricEvaluationResult(evaluationResult, condition);
}
.setMetricKey(randomAlphanumeric(96))
.setOperator(QualityGate.Operator.values()[random.nextInt(QualityGate.Operator.values().length)])
.setErrorThreshold(randomAlphanumeric(22))
- .setWarningThreshold(randomAlphanumeric(23))
.setOnLeakPeriod(random.nextBoolean())
.build(QualityGate.EvaluationStatus.OK, randomAlphanumeric(33));
QualityGate qualityGate = newQualityGateBuilder()
Condition qgCondition = new Condition(
condition.getMetricKey(),
Condition.Operator.valueOf(condition.getOperator().name()),
- condition.getErrorThreshold(),
- condition.getWarningThreshold()
- );
+ condition.getErrorThreshold());
webQualityGate = EvaluatedQualityGate.newBuilder()
.setQualityGate(new org.sonar.server.qualitygate.QualityGate(qualityGate.getId(), qualityGate.getName(), Collections.singleton(qgCondition)))
.setStatus(Metric.Level.valueOf(qualityGate.getStatus().name()))
private String operator;
- private String warningThreshold;
-
private String errorThreshold;
private Date createdAt;
return this;
}
- public String getWarningThreshold() {
- return warningThreshold;
- }
-
- public QualityGateConditionDto setWarningThreshold(@Nullable String warningThreshold) {
- this.warningThreshold = warningThreshold;
- return this;
- }
-
public String getErrorThreshold() {
return errorThreshold;
}
- public QualityGateConditionDto setErrorThreshold(@Nullable String errorThreshold) {
+ public QualityGateConditionDto setErrorThreshold(String errorThreshold) {
this.errorThreshold = errorThreshold;
return this;
}
<mapper namespace="org.sonar.db.qualitygate.QualityGateConditionMapper">
<insert id="insert" parameterType="QualityGateCondition" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
- insert into quality_gate_conditions (qgate_id, metric_id, operator, value_error, value_warning, created_at,
- updated_at)
- values (#{qualityGateId}, #{metricId}, #{operator}, #{errorThreshold}, #{warningThreshold}, #{createdAt},
- #{updatedAt})
+ insert into quality_gate_conditions (qgate_id, metric_id, operator, value_error, created_at, updated_at)
+ values (#{qualityGateId}, #{metricId}, #{operator}, #{errorThreshold}, #{createdAt}, #{updatedAt})
</insert>
<sql id="conditionColumns">
- id, qgate_id as qualityGateId, metric_id as metricId, operator, value_warning as warningThreshold, value_error as
- errorThreshold,
+ id, qgate_id as qualityGateId, metric_id as metricId, operator, value_error as errorThreshold,
created_at as createdAt, updated_at as updatedAt
</sql>
update quality_gate_conditions set
metric_id=#{metricId},
operator=#{operator},
- value_warning=#{warningThreshold},
value_error=#{errorThreshold},
updated_at=#{updatedAt}
where id=#{id}
import static org.assertj.core.api.Assertions.entry;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
import static org.sonar.api.measures.Metric.ValueType.DATA;
import static org.sonar.api.measures.Metric.ValueType.DISTRIB;
import static org.sonar.api.measures.Metric.ValueType.INT;
ComponentDto project2 = dbTester.components().insertPrivateProject(organization);
ComponentDto project3 = dbTester.components().insertPrivateProject(organization);
MetricDto metric = dbTester.measures().insertMetric(m -> m.setValueType(LEVEL.name()).setKey("alert_status"));
- dbTester.measures().insertLiveMeasure(project1, metric, m -> m.setValue(null).setData(WARN.name()));
dbTester.measures().insertLiveMeasure(project2, metric, m -> m.setValue(null).setData(OK.name()));
dbTester.measures().insertLiveMeasure(project3, metric, m -> m.setValue(null).setData(ERROR.name()));
Map<String, ProjectMeasures> docsById = createResultSetAndReturnDocsById();
- assertThat(docsById.get(project1.uuid()).getMeasures().getQualityGateStatus()).isEqualTo("WARN");
assertThat(docsById.get(project2.uuid()).getMeasures().getQualityGateStatus()).isEqualTo("OK");
assertThat(docsById.get(project3.uuid()).getMeasures().getQualityGateStatus()).isEqualTo("ERROR");
}
public class QualityGateConditionDaoTest {
private static final String[] COLUMNS_WITHOUT_TIMESTAMPS = {
- "id", "qgate_id", "metric_id", "operator", "value_warning", "value_error"
+ "id", "qgate_id", "metric_id", "operator", "value_error"
};
@Rule
public void testInsert() {
dbTester.prepareDbUnit(getClass(), "insert.xml");
QualityGateConditionDto newCondition = new QualityGateConditionDto()
- .setQualityGateId(1L).setMetricId(2L).setOperator("GT").setWarningThreshold("10").setErrorThreshold("20");
+ .setQualityGateId(1L).setMetricId(2L).setOperator("GT").setErrorThreshold("20");
underTest.insert(newCondition, dbTester.getSession());
dbTester.commit();
- dbTester.assertDbUnitTable(getClass(), "insert-result.xml", "quality_gate_conditions", "metric_id", "operator", "error_value", "warning_value");
+ dbTester.assertDbUnitTable(getClass(), "insert-result.xml", "quality_gate_conditions", "metric_id", "operator", "error_value");
assertThat(newCondition.getId()).isNotNull();
}
assertThat(selectById.getMetricId()).isEqualTo(2L);
assertThat(selectById.getOperator()).isEqualTo("<");
assertThat(selectById.getQualityGateId()).isEqualTo(1L);
- assertThat(selectById.getWarningThreshold()).isEqualTo("10");
assertThat(selectById.getErrorThreshold()).isEqualTo("20");
assertThat(underTest.selectById(42L, dbSession)).isNull();
}
public void testUpdate() {
dbTester.prepareDbUnit(getClass(), "selectForQualityGate.xml");
- underTest.update(new QualityGateConditionDto().setId(1L).setMetricId(7L).setOperator(">").setWarningThreshold("50").setErrorThreshold("80"), dbSession);
+ underTest.update(new QualityGateConditionDto().setId(1L).setMetricId(7L).setOperator(">").setErrorThreshold("80"), dbSession);
dbSession.commit();
dbTester.assertDbUnitTable(getClass(), "update-result.xml", "quality_gate_conditions", COLUMNS_WITHOUT_TIMESTAMPS);
QualityGateConditionDto condition = new QualityGateConditionDto().setQualityGateId(qualityGate.getId())
.setMetricId(metric.getId())
.setOperator("GT")
- .setWarningThreshold(randomNumeric(10))
.setErrorThreshold(randomNumeric(10));
Arrays.stream(dtoPopulators).forEach(dtoPopulator -> dtoPopulator.accept(condition));
dbClient.gateConditionDao().insert(condition, dbSession);
<dataset>
-
- <quality_gate_conditions id="1" qgate_id="1" metric_id="7" operator=">" value_warning="50" value_error="80"/>
- <quality_gate_conditions id="2" qgate_id="1" metric_id="3" operator="<" value_warning="10" value_error="20"/>
- <quality_gate_conditions id="3" qgate_id="1" metric_id="4" operator="<" value_warning="10" value_error="[null]"/>
- <quality_gate_conditions id="4" qgate_id="2" metric_id="5" operator="<" value_warning="[null]" value_error="20"/>
- <quality_gate_conditions id="5" qgate_id="2" metric_id="6" operator="<" value_warning="[null]" value_error="20"/>
-
+ <quality_gate_conditions id="1" qgate_id="1" metric_id="7" operator=">" value_error="80" />
+ <quality_gate_conditions id="2" qgate_id="1" metric_id="3" operator="<" value_error="20" />
+ <quality_gate_conditions id="3" qgate_id="1" metric_id="4" operator="<" value_error="[null]" />
+ <quality_gate_conditions id="4" qgate_id="2" metric_id="5" operator="<" value_error="20" />
+ <quality_gate_conditions id="5" qgate_id="2" metric_id="6" operator="<" value_error="20" />
</dataset>
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.FIELD_ANALYSED_AT;
import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.FIELD_DISTRIB_LANGUAGE;
import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.FIELD_DISTRIB_NCLOC;
public class ProjectMeasuresDoc extends BaseDoc {
- public static final Map<String, Integer> QUALITY_GATE_STATUS = ImmutableMap.of(OK.name(), 1, WARN.name(), 2, ERROR.name(), 3);
+ public static final Map<String, Integer> QUALITY_GATE_STATUS = ImmutableMap.of(OK.name(), 1, ERROR.name(), 2);
public ProjectMeasuresDoc() {
super(new HashMap<>(8));
package org.sonar.server.qualitygate;
import java.util.Objects;
-import java.util.Optional;
import java.util.stream.Stream;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.sonar.db.qualitygate.QualityGateConditionDto;
-import static com.google.common.base.Strings.emptyToNull;
import static java.util.Objects.requireNonNull;
@Immutable
private final String metricKey;
private final Operator operator;
- @CheckForNull
- private final String warningThreshold;
- @CheckForNull
private final String errorThreshold;
private final boolean onLeakPeriod;
- public Condition(String metricKey, Operator operator,
- @Nullable String errorThreshold, @Nullable String warningThreshold) {
+ public Condition(String metricKey, Operator operator, String errorThreshold) {
this.metricKey = requireNonNull(metricKey, "metricKey can't be null");
this.operator = requireNonNull(operator, "operator can't be null");
+ this.errorThreshold = requireNonNull(errorThreshold, "errorThreshold can't be null");
this.onLeakPeriod = metricKey.startsWith("new_");
- this.errorThreshold = emptyToNull(errorThreshold);
- this.warningThreshold = emptyToNull(warningThreshold);
}
public String getMetricKey() {
return operator;
}
- public Optional<String> getWarningThreshold() {
- return Optional.ofNullable(warningThreshold);
- }
-
- public Optional<String> getErrorThreshold() {
- return Optional.ofNullable(errorThreshold);
+ public String getErrorThreshold() {
+ return errorThreshold;
}
@Override
Condition condition = (Condition) o;
return Objects.equals(metricKey, condition.metricKey) &&
operator == condition.operator &&
- Objects.equals(warningThreshold, condition.warningThreshold) &&
Objects.equals(errorThreshold, condition.errorThreshold);
}
@Override
public int hashCode() {
- return Objects.hash(metricKey, operator, warningThreshold, errorThreshold);
+ return Objects.hash(metricKey, operator, errorThreshold);
}
@Override
return "Condition{" +
"metricKey='" + metricKey + '\'' +
", operator=" + operator +
- ", warningThreshold=" + toString(warningThreshold) +
", errorThreshold=" + toString(errorThreshold) +
'}';
}
- private static String toString(@Nullable String errorThreshold) {
- if (errorThreshold == null) {
- return null;
- }
+ private static String toString(String errorThreshold) {
return '\'' + errorThreshold + '\'';
}
}
ValueType type = measure.get().getType();
- return evaluateCondition(condition, type, value.get(), true)
- .orElseGet(() -> evaluateCondition(condition, type, value.get(), false)
+ return evaluateCondition(condition, type, value.get())
+ .orElseGet(() -> evaluateCondition(condition, type, value.get())
.orElseGet(() -> new EvaluatedCondition(condition, EvaluationStatus.OK, value.get().toString())));
}
/**
- * Evaluates the error or warning condition. Returns empty if threshold or measure value is not defined.
+ * Evaluates the error condition. Returns empty if threshold or measure value is not defined.
*/
- private static Optional<EvaluatedCondition> evaluateCondition(Condition condition, ValueType type, Comparable value, boolean error) {
- Optional<Comparable> threshold = getThreshold(condition, type, error);
- if (!threshold.isPresent()) {
- return Optional.empty();
- }
+ private static Optional<EvaluatedCondition> evaluateCondition(Condition condition, ValueType type, Comparable value) {
+ Comparable threshold = getThreshold(condition, type);
- if (reachThreshold(value, threshold.get(), condition)) {
- EvaluationStatus status = error ? EvaluationStatus.ERROR : EvaluationStatus.WARN;
- return of(new EvaluatedCondition(condition, status, value.toString()));
+ if (reachThreshold(value, threshold, condition)) {
+ return of(new EvaluatedCondition(condition, EvaluationStatus.ERROR, value.toString()));
}
return Optional.empty();
}
- private static Optional<Comparable> getThreshold(Condition condition, ValueType valueType, boolean error) {
- Optional<String> valString = error ? condition.getErrorThreshold() : condition.getWarningThreshold();
- return valString.map(s -> {
- try {
- switch (valueType) {
- case BOOL:
- return parseInteger(s) == 1;
- case INT:
- case RATING:
- return parseInteger(s);
- case MILLISEC:
- case WORK_DUR:
- return Long.parseLong(s);
- case FLOAT:
- case PERCENT:
- return Double.parseDouble(s);
- case STRING:
- case LEVEL:
- return s;
- default:
- throw new IllegalArgumentException(String.format("Unsupported value type %s. Cannot convert condition value", valueType));
- }
- } catch (NumberFormatException badValueFormat) {
- throw new IllegalArgumentException(String.format(
- "Quality Gate: unable to parse threshold '%s' to compare against %s", s, condition.getMetricKey()));
+ private static Comparable getThreshold(Condition condition, ValueType valueType) {
+ String valString = condition.getErrorThreshold();
+ try {
+ switch (valueType) {
+ case BOOL:
+ return parseInteger(valString) == 1;
+ case INT:
+ case RATING:
+ return parseInteger(valString);
+ case MILLISEC:
+ case WORK_DUR:
+ return Long.parseLong(valString);
+ case FLOAT:
+ case PERCENT:
+ return Double.parseDouble(valString);
+ case STRING:
+ case LEVEL:
+ return valueType;
+ default:
+ throw new IllegalArgumentException(String.format("Unsupported value type %s. Cannot convert condition value", valueType));
}
- });
+ } catch (NumberFormatException badValueFormat) {
+ throw new IllegalArgumentException(String.format(
+ "Quality Gate: unable to parse threshold '%s' to compare against %s", valString, condition.getMetricKey()));
+ }
}
private static Optional<Comparable> getMeasureValue(Condition condition, QualityGateEvaluator.Measure measure) {
*/
NO_VALUE,
/**
- * Condition evaluated as OK, neither error nor warning thresholds have been reached.
+ * Condition evaluated as OK, error thresholds hasn't been reached.
*/
OK,
/**
- * Condition evaluated as WARN, only warning thresholds has been reached.
- */
- WARN,
- /**
- * Condition evaluated as ERROR, error thresholds has been reached (and most likely warning thresholds too).
+ * Condition evaluated as ERROR, error thresholds has been reached.
*/
ERROR
}
if (statuses.contains(EvaluationStatus.ERROR)) {
return Level.ERROR;
}
- if (statuses.contains(EvaluationStatus.WARN)) {
- return Level.WARN;
- }
return Level.OK;
}
}
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.List;
-import javax.annotation.CheckForNull;
import org.sonar.api.measures.CoreMetrics;
import static org.sonar.db.qualitygate.QualityGateConditionDto.OPERATOR_GREATER_THAN;
new Condition(CoreMetrics.REOPENED_ISSUES_KEY, OPERATOR_GREATER_THAN, "0"));
public static final QualityGate GATE = new QualityGate(String.valueOf(ID), NAME, ImmutableSet.of(
- new org.sonar.server.qualitygate.Condition(CoreMetrics.OPEN_ISSUES_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0", null),
- new org.sonar.server.qualitygate.Condition(CoreMetrics.REOPENED_ISSUES_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0", null)));
+ new org.sonar.server.qualitygate.Condition(CoreMetrics.OPEN_ISSUES_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0"),
+ new org.sonar.server.qualitygate.Condition(CoreMetrics.REOPENED_ISSUES_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0")));
private ShortLivingBranchQualityGate() {
// prevents instantiation
public String getErrorThreshold() {
return errorThreshold;
}
-
- @CheckForNull
- public String getWarnThreshold() {
- return null;
- }
}
}
evaluatedCondition.getValue().ifPresent(t -> writer.prop("value", t));
writer
.prop(PROPERTY_STATUS, evaluatedCondition.getStatus().name())
- .prop("errorThreshold", condition.getErrorThreshold().orElse(null))
- .prop("warningThreshold", condition.getWarningThreshold().orElse(null))
+ .prop("errorThreshold", condition.getErrorThreshold())
.endObject();
}
writer
testOnLeak(newFakeMeasureOnLeak(10), Condition.Operator.LESS_THAN, "11", EvaluatedCondition.EvaluationStatus.ERROR, "10");
}
+ @Test
+ public void evaluate_throws_IAE_if_fail_to_parse_threshold() {
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Quality Gate: unable to parse threshold '9bar' to compare against foo");
+
+ test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "9bar", EvaluatedCondition.EvaluationStatus.ERROR, "10da");
+ }
+
@Test
public void no_value_present() {
test(new FakeMeasure((Integer) null), Condition.Operator.LESS_THAN, "9", EvaluatedCondition.EvaluationStatus.OK, null);
@Test
public void empty_warning_condition() {
- test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "9", null, EvaluatedCondition.EvaluationStatus.OK, "10");
- test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "9", "", EvaluatedCondition.EvaluationStatus.OK, "10");
- test(new FakeMeasure(3), Condition.Operator.LESS_THAN, "9", "", EvaluatedCondition.EvaluationStatus.ERROR, "3");
- }
-
- private void test(@Nullable QualityGateEvaluator.Measure measure, Condition.Operator operator, String errorThreshold, EvaluatedCondition.EvaluationStatus expectedStatus,
- @Nullable String expectedValue) {
- test(measure, operator, errorThreshold, null, expectedStatus, expectedValue);
+ test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "9", EvaluatedCondition.EvaluationStatus.OK, "10");
+ test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "9", EvaluatedCondition.EvaluationStatus.OK, "10");
+ test(new FakeMeasure(3), Condition.Operator.LESS_THAN, "9", EvaluatedCondition.EvaluationStatus.ERROR, "3");
}
- private void test(@Nullable QualityGateEvaluator.Measure measure, Condition.Operator operator, String errorThreshold, @Nullable String warningThreshold,
- EvaluatedCondition.EvaluationStatus expectedStatus, @Nullable String expectedValue) {
- Condition condition = new Condition("foo", operator, errorThreshold, warningThreshold);
+ private void test(@Nullable QualityGateEvaluator.Measure measure, Condition.Operator operator, String errorThreshold, EvaluatedCondition.EvaluationStatus expectedStatus, @Nullable String expectedValue) {
+ Condition condition = new Condition("foo", operator, errorThreshold);
EvaluatedCondition result = ConditionEvaluator.evaluate(condition, new FakeMeasures(measure));
private void testOnLeak(QualityGateEvaluator.Measure measure, Condition.Operator operator, String errorThreshold, EvaluatedCondition.EvaluationStatus expectedStatus,
@Nullable String expectedValue) {
- Condition condition = new Condition("new_foo", operator, errorThreshold, null);
+ Condition condition = new Condition("new_foo", operator, errorThreshold);
EvaluatedCondition result = ConditionEvaluator.evaluate(condition, new FakeMeasures(measure));
private static final String METRIC_KEY = "metric_key";
private static final Condition.Operator OPERATOR = Condition.Operator.EQUALS;
private static final String ERROR_THRESHOLD = "2";
- private static final String WARN_THRESHOLD = "4";
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private Condition underTest = new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD);
+ private Condition underTest = new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD);
@Test
public void constructor_throws_NPE_if_metricKey_is_null() {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("metricKey can't be null");
- new Condition(null, OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD);
+ new Condition(null, OPERATOR, ERROR_THRESHOLD);
}
@Test
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("operator can't be null");
- new Condition(METRIC_KEY, null, ERROR_THRESHOLD, WARN_THRESHOLD);
+ new Condition(METRIC_KEY, null, ERROR_THRESHOLD);
}
@Test
- public void errorThreshold_can_be_null() {
- Condition underTest = new Condition(METRIC_KEY, OPERATOR, null, WARN_THRESHOLD);
-
- assertThat(underTest.getErrorThreshold()).isEmpty();
- }
-
- @Test
- public void warnThreshold_can_be_null() {
- Condition underTest = new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, null);
+ public void constructor_throws_NPE_if_errorThreshold_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("errorThreshold can't be null");
- assertThat(underTest.getWarningThreshold()).isEmpty();
+ new Condition(METRIC_KEY, OPERATOR, null);
}
@Test
assertThat(underTest.getMetricKey()).isEqualTo(METRIC_KEY);
assertThat(underTest.getOperator()).isEqualTo(OPERATOR);
assertThat(underTest.getErrorThreshold()).contains(ERROR_THRESHOLD);
- assertThat(underTest.getWarningThreshold()).contains(WARN_THRESHOLD);
}
@Test
public void toString_is_override() {
assertThat(underTest.toString())
- .isEqualTo("Condition{metricKey='metric_key', operator=EQUALS, warningThreshold='4', errorThreshold='2'}");
- }
-
- @Test
- public void toString_does_not_quote_nulls() {
- Condition withNulls = new Condition("metric_key", Condition.Operator.LESS_THAN, null, null);
- assertThat(withNulls.toString())
- .isEqualTo("Condition{metricKey='metric_key', operator=LESS_THAN, warningThreshold=null, errorThreshold=null}");
+ .isEqualTo("Condition{metricKey='metric_key', operator=EQUALS, errorThreshold='2'}");
}
@Test
assertThat(underTest).isEqualTo(underTest);
assertThat(underTest).isNotEqualTo(null);
assertThat(underTest).isNotEqualTo(new Object());
- assertThat(underTest).isEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD));
- assertThat(underTest).isNotEqualTo(new Condition("other_metric_key", OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD));
+ assertThat(underTest).isEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD));
+ assertThat(underTest).isNotEqualTo(new Condition("other_metric_key", OPERATOR, ERROR_THRESHOLD));
Arrays.stream(Condition.Operator.values())
.filter(s -> !OPERATOR.equals(s))
.forEach(otherOperator -> assertThat(underTest)
- .isNotEqualTo(new Condition(METRIC_KEY, otherOperator, ERROR_THRESHOLD, WARN_THRESHOLD)));
- assertThat(underTest).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, null, WARN_THRESHOLD));
- assertThat(underTest).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, "other_error_threshold", WARN_THRESHOLD));
- assertThat(underTest).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, null));
- assertThat(underTest).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, "other_warn_threshold"));
+ .isNotEqualTo(new Condition(METRIC_KEY, otherOperator, ERROR_THRESHOLD)));
+ assertThat(underTest).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, "other_error_threshold"));
}
@Test
assertThat(underTest.hashCode()).isEqualTo(underTest.hashCode());
assertThat(underTest.hashCode()).isNotEqualTo(null);
assertThat(underTest.hashCode()).isNotEqualTo(new Object().hashCode());
- assertThat(underTest.hashCode()).isEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD).hashCode());
- assertThat(underTest.hashCode()).isNotEqualTo(new Condition("other_metric_key", OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD).hashCode());
+ assertThat(underTest.hashCode()).isEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD).hashCode());
+ assertThat(underTest.hashCode()).isNotEqualTo(new Condition("other_metric_key", OPERATOR, ERROR_THRESHOLD).hashCode());
Arrays.stream(Condition.Operator.values())
.filter(s -> !OPERATOR.equals(s))
.forEach(otherOperator -> assertThat(underTest.hashCode())
- .isNotEqualTo(new Condition(METRIC_KEY, otherOperator, ERROR_THRESHOLD, WARN_THRESHOLD).hashCode()));
- assertThat(underTest.hashCode()).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, null, WARN_THRESHOLD).hashCode());
- assertThat(underTest.hashCode()).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, "other_error_threshold", WARN_THRESHOLD).hashCode());
- assertThat(underTest.hashCode()).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, null).hashCode());
- assertThat(underTest.hashCode()).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, "other_warn_threshold").hashCode());
+ .isNotEqualTo(new Condition(METRIC_KEY, otherOperator, ERROR_THRESHOLD).hashCode()));
+ assertThat(underTest.hashCode()).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, "other_error_threshold").hashCode());
}
}
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.server.qualitygate.Condition.Operator.EQUALS;
+import static org.sonar.server.qualitygate.EvaluatedCondition.EvaluationStatus.ERROR;
import static org.sonar.server.qualitygate.EvaluatedCondition.EvaluationStatus.OK;
-import static org.sonar.server.qualitygate.EvaluatedCondition.EvaluationStatus.WARN;
public class EvaluatedConditionTest {
- private static final Condition CONDITION_1 = new Condition("metricKey", EQUALS, "2", "4");
+ private static final Condition CONDITION_1 = new Condition("metricKey", EQUALS, "2");
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private EvaluatedCondition underTest = new EvaluatedCondition(CONDITION_1, WARN, "value");
+ private EvaluatedCondition underTest = new EvaluatedCondition(CONDITION_1, ERROR, "value");
@Test
public void constructor_throws_NPE_if_condition_is_null() {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("condition can't be null");
- new EvaluatedCondition(null, WARN, "value");
+ new EvaluatedCondition(null, ERROR, "value");
}
@Test
@Test
public void constructor_accepts_null_value() {
- EvaluatedCondition underTest = new EvaluatedCondition(CONDITION_1, WARN, null);
+ EvaluatedCondition underTest = new EvaluatedCondition(CONDITION_1, ERROR, null);
assertThat(underTest.getValue()).isEmpty();
}
@Test
public void verify_getters() {
- EvaluatedCondition underTest = new EvaluatedCondition(CONDITION_1, WARN, "value");
+ EvaluatedCondition underTest = new EvaluatedCondition(CONDITION_1, ERROR, "value");
assertThat(underTest.getCondition()).isEqualTo(CONDITION_1);
- assertThat(underTest.getStatus()).isEqualTo(WARN);
+ assertThat(underTest.getStatus()).isEqualTo(ERROR);
assertThat(underTest.getValue()).contains("value");
}
@Test
public void override_toString() {
assertThat(underTest.toString()).isEqualTo("EvaluatedCondition{condition=" +
- "Condition{metricKey='metricKey', operator=EQUALS, warningThreshold='4', errorThreshold='2'}, " +
- "status=WARN, value='value'}");
+ "Condition{metricKey='metricKey', operator=EQUALS, errorThreshold='2'}, " +
+ "status=ERROR, value='value'}");
}
@Test
public void toString_does_not_quote_null_value() {
- EvaluatedCondition underTest = new EvaluatedCondition(CONDITION_1, WARN, null);
+ EvaluatedCondition underTest = new EvaluatedCondition(CONDITION_1, ERROR, null);
assertThat(underTest.toString()).isEqualTo("EvaluatedCondition{condition=" +
- "Condition{metricKey='metricKey', operator=EQUALS, warningThreshold='4', errorThreshold='2'}, " +
- "status=WARN, value=null}");
+ "Condition{metricKey='metricKey', operator=EQUALS, errorThreshold='2'}, " +
+ "status=ERROR, value=null}");
}
@Test
public void equals_is_based_on_all_fields() {
assertThat(underTest).isEqualTo(underTest);
- assertThat(underTest).isEqualTo(new EvaluatedCondition(CONDITION_1, WARN, "value"));
+ assertThat(underTest).isEqualTo(new EvaluatedCondition(CONDITION_1, ERROR, "value"));
assertThat(underTest).isNotEqualTo(null);
assertThat(underTest).isNotEqualTo(new Object());
- assertThat(underTest).isNotEqualTo(new EvaluatedCondition(new Condition("other_metric", EQUALS, "a", "b"), WARN, "value"));
+ assertThat(underTest).isNotEqualTo(new EvaluatedCondition(new Condition("other_metric", EQUALS, "a"), ERROR, "value"));
assertThat(underTest).isNotEqualTo(new EvaluatedCondition(CONDITION_1, OK, "value"));
- assertThat(underTest).isNotEqualTo(new EvaluatedCondition(CONDITION_1, WARN, null));
- assertThat(underTest).isNotEqualTo(new EvaluatedCondition(CONDITION_1, WARN, "other_value"));
+ assertThat(underTest).isNotEqualTo(new EvaluatedCondition(CONDITION_1, ERROR, null));
+ assertThat(underTest).isNotEqualTo(new EvaluatedCondition(CONDITION_1, ERROR, "other_value"));
}
@Test
public void hashcode_is_based_on_all_fields() {
assertThat(underTest.hashCode()).isEqualTo(underTest.hashCode());
- assertThat(underTest.hashCode()).isEqualTo(new EvaluatedCondition(CONDITION_1, WARN, "value").hashCode());
+ assertThat(underTest.hashCode()).isEqualTo(new EvaluatedCondition(CONDITION_1, ERROR, "value").hashCode());
assertThat(underTest.hashCode()).isNotEqualTo(null);
assertThat(underTest.hashCode()).isNotEqualTo(new Object().hashCode());
- assertThat(underTest.hashCode()).isNotEqualTo(new EvaluatedCondition(new Condition("other_metric", EQUALS, "a", "b"), WARN, "value").hashCode());
+ assertThat(underTest.hashCode()).isNotEqualTo(new EvaluatedCondition(new Condition("other_metric", EQUALS, "a"), ERROR, "value").hashCode());
assertThat(underTest.hashCode()).isNotEqualTo(new EvaluatedCondition(CONDITION_1, OK, "value").hashCode());
- assertThat(underTest.hashCode()).isNotEqualTo(new EvaluatedCondition(CONDITION_1, WARN, null).hashCode());
- assertThat(underTest.hashCode()).isNotEqualTo(new EvaluatedCondition(CONDITION_1, WARN, "other_value").hashCode());
+ assertThat(underTest.hashCode()).isNotEqualTo(new EvaluatedCondition(CONDITION_1, ERROR, null).hashCode());
+ assertThat(underTest.hashCode()).isNotEqualTo(new EvaluatedCondition(CONDITION_1, ERROR, "other_value").hashCode());
}
}
private static final String QUALITY_GATE_ID = "qg_id";
private static final String QUALITY_GATE_NAME = "qg_name";
private static final QualityGate NO_CONDITION_QUALITY_GATE = new QualityGate(QUALITY_GATE_ID, QUALITY_GATE_NAME, emptySet());
- private static final Condition CONDITION_1 = new Condition("metric_key", Condition.Operator.LESS_THAN, "2", "4");
- private static final Condition CONDITION_2 = new Condition("metric_key_2", Condition.Operator.GREATER_THAN, "6", "12");
+ private static final Condition CONDITION_1 = new Condition("metric_key", Condition.Operator.LESS_THAN, "2");
+ private static final Condition CONDITION_2 = new Condition("metric_key_2", Condition.Operator.GREATER_THAN, "6");
private static final QualityGate ONE_CONDITION_QUALITY_GATE = new QualityGate(QUALITY_GATE_ID, QUALITY_GATE_NAME, singleton(CONDITION_1));
@Rule
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("condition can't be null");
- builder.addCondition(null, EvaluatedCondition.EvaluationStatus.WARN, "a_value");
+ builder.addCondition(null, EvaluatedCondition.EvaluationStatus.ERROR, "a_value");
}
@Test
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("status can't be null");
- builder.addCondition(new Condition("metric_key", Condition.Operator.LESS_THAN, "2", "4"), null, "a_value");
+ builder.addCondition(new Condition("metric_key", Condition.Operator.LESS_THAN, "2"), null, "a_value");
}
@Test
.setQualityGate(qualityGate)
.setStatus(randomStatus)
.addCondition(CONDITION_1, randomEvaluationStatus, randomValue)
- .addCondition(CONDITION_2, EvaluatedCondition.EvaluationStatus.WARN, "bad")
+ .addCondition(CONDITION_2, EvaluatedCondition.EvaluationStatus.ERROR, "bad")
.build();
assertThat(underTest.getQualityGate()).isEqualTo(qualityGate);
assertThat(underTest.getStatus()).isEqualTo(randomStatus);
assertThat(underTest.getEvaluatedConditions()).containsOnly(
new EvaluatedCondition(CONDITION_1, randomEvaluationStatus, randomValue),
- new EvaluatedCondition(CONDITION_2, EvaluatedCondition.EvaluationStatus.WARN, "bad"));
+ new EvaluatedCondition(CONDITION_2, EvaluatedCondition.EvaluationStatus.ERROR, "bad"));
}
@Test
public void equals_is_based_on_all_fields() {
EvaluatedQualityGate.Builder builder = this.builder
.setQualityGate(ONE_CONDITION_QUALITY_GATE)
- .setStatus(Level.WARN)
- .addCondition(CONDITION_1, EvaluatedCondition.EvaluationStatus.WARN, "foo");
+ .setStatus(Level.ERROR)
+ .addCondition(CONDITION_1, EvaluatedCondition.EvaluationStatus.ERROR, "foo");
EvaluatedQualityGate underTest = builder.build();
assertThat(underTest).isEqualTo(builder.build());
assertThat(underTest).isNotEqualTo(builder.setQualityGate(ONE_CONDITION_QUALITY_GATE).setStatus(Level.OK).build());
assertThat(underTest).isNotEqualTo(newBuilder()
.setQualityGate(ONE_CONDITION_QUALITY_GATE)
- .setStatus(Level.WARN)
+ .setStatus(Level.ERROR)
.addCondition(CONDITION_1, EvaluatedCondition.EvaluationStatus.OK, "foo")
.build());
}
public void hashcode_is_based_on_all_fields() {
EvaluatedQualityGate.Builder builder = this.builder
.setQualityGate(ONE_CONDITION_QUALITY_GATE)
- .setStatus(Level.WARN)
- .addCondition(CONDITION_1, EvaluatedCondition.EvaluationStatus.WARN, "foo");
+ .setStatus(Level.ERROR)
+ .addCondition(CONDITION_1, EvaluatedCondition.EvaluationStatus.ERROR, "foo");
EvaluatedQualityGate underTest = builder.build();
assertThat(underTest.hashCode()).isEqualTo(builder.build().hashCode());
assertThat(underTest.hashCode()).isNotEqualTo(builder.setQualityGate(ONE_CONDITION_QUALITY_GATE).setStatus(Level.OK).build().hashCode());
assertThat(underTest.hashCode()).isNotEqualTo(newBuilder()
.setQualityGate(ONE_CONDITION_QUALITY_GATE)
- .setStatus(Level.WARN)
+ .setStatus(Level.ERROR)
.addCondition(CONDITION_1, EvaluatedCondition.EvaluationStatus.OK, "foo")
.build().hashCode());
}
public class QualityGateTest {
private static final String QUALIGATE_ID = "qg_id";
private static final String QUALIGATE_NAME = "qg_name";
- private static final Condition CONDITION_1 = new Condition("m1", Condition.Operator.EQUALS, "1", "2");
- private static final Condition CONDITION_2 = new Condition("m2", Condition.Operator.LESS_THAN, "2", "4");
+ private static final Condition CONDITION_1 = new Condition("m1", Condition.Operator.EQUALS, "1");
+ private static final Condition CONDITION_2 = new Condition("m2", Condition.Operator.LESS_THAN, "2");
@Rule
public ExpectedException expectedException = ExpectedException.none();
Random random = new Random();
Set<Condition> conditions = Stream.of(
IntStream.range(0, random.nextInt(5))
- .mapToObj(i -> new Condition("m_before_" + i, Condition.Operator.EQUALS, null, null)),
+ .mapToObj(i -> new Condition("m_before_" + i, Condition.Operator.EQUALS, "10")),
Stream.of((Condition) null),
IntStream.range(0, random.nextInt(5))
- .mapToObj(i -> new Condition("m_after_" + i, Condition.Operator.EQUALS, null, null)))
+ .mapToObj(i -> new Condition("m_after_" + i, Condition.Operator.EQUALS, "10")))
.flatMap(s -> s)
.collect(Collectors.toSet());
QualityGate underTest = new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_2));
assertThat(underTest.toString()).isEqualTo("QualityGate{id=qg_id, name='qg_name', conditions=[" +
- "Condition{metricKey='m2', operator=LESS_THAN, warningThreshold='4', errorThreshold='2'}" +
+ "Condition{metricKey='m2', operator=LESS_THAN, errorThreshold='2'}" +
"]}");
}
assertThat(underTest).isNotEqualTo(new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_1)));
assertThat(underTest).isNotEqualTo(new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_2)));
assertThat(underTest).isNotEqualTo(
- new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_1, CONDITION_2, new Condition("new", Condition.Operator.GREATER_THAN, "a", "b"))));
+ new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_1, CONDITION_2, new Condition("new", Condition.Operator.GREATER_THAN, "a"))));
}
@Test
assertThat(underTest.hashCode()).isNotEqualTo(new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_1)).hashCode());
assertThat(underTest.hashCode()).isNotEqualTo(new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_2)).hashCode());
assertThat(underTest.hashCode()).isNotEqualTo(
- new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_1, CONDITION_2, new Condition("new", Condition.Operator.GREATER_THAN, "a", "b"))).hashCode());
+ new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_1, CONDITION_2, new Condition("new", Condition.Operator.GREATER_THAN, "a"))).hashCode());
}
}
@Test
public void defines_short_living_branches_hardcoded_quality_gate_conditions() {
assertThat(ShortLivingBranchQualityGate.CONDITIONS)
- .extracting(Condition::getMetricKey, Condition::getOperator, Condition::getErrorThreshold, Condition::getWarnThreshold)
+ .extracting(Condition::getMetricKey, Condition::getOperator, Condition::getErrorThreshold)
.containsExactly(
- tuple(CoreMetrics.OPEN_ISSUES_KEY, "GT", "0", null),
- tuple(CoreMetrics.REOPENED_ISSUES_KEY, "GT", "0", null));
+ tuple(CoreMetrics.OPEN_ISSUES_KEY, "GT", "0"),
+ tuple(CoreMetrics.REOPENED_ISSUES_KEY, "GT", "0"));
}
}
private final Branch branch = new Branch(true, "name", Branch.Type.SHORT);
private final EvaluatedQualityGate qualityGate = EvaluatedQualityGate.newBuilder()
.setQualityGate(new QualityGate("id", "name", emptySet()))
- .setStatus(Metric.Level.WARN)
+ .setStatus(Metric.Level.ERROR)
.build();
private final Map<String, String> properties = ImmutableMap.of("a", "b");
private ProjectAnalysis underTest = new ProjectAnalysis(project, ceTask, analysis, branch, qualityGate, 1L, properties);
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, branch, null, 1L, properties));
EvaluatedQualityGate otherQualityGate = EvaluatedQualityGate.newBuilder()
.setQualityGate(new QualityGate("A", "B", emptySet()))
- .setStatus(Metric.Level.WARN)
+ .setStatus(Metric.Level.ERROR)
.build();
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, branch, otherQualityGate, 1L, properties));
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, branch, qualityGate, null, properties));
assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, branch, null, 1L, properties).hashCode());
EvaluatedQualityGate otherQualityGate = EvaluatedQualityGate.newBuilder()
.setQualityGate(new QualityGate("A", "B", emptySet()))
- .setStatus(Metric.Level.WARN)
+ .setStatus(Metric.Level.ERROR)
.build();
assertThat(underTest.hashCode())
.isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, branch, otherQualityGate, 1L, properties).hashCode());
@Test
public void verify_toString() {
assertThat(underTest.toString()).isEqualTo(
- "ProjectAnalysis{project=Project{uuid='uuid', key='key', name='name'}, ceTask=CeTask{id='id', status=SUCCESS}, branch=Branch{main=true, name='name', type=SHORT}, qualityGate=EvaluatedQualityGate{qualityGate=QualityGate{id=id, name='name', conditions=[]}, status=WARN, evaluatedConditions=[]}, updatedAt=1, properties={a=b}, analysis=Analysis{uuid='analysis_uuid', date=1500}}");
+ "ProjectAnalysis{project=Project{uuid='uuid', key='key', name='name'}, ceTask=CeTask{id='id', status=SUCCESS}, branch=Branch{main=true, name='name', type=SHORT}, qualityGate=EvaluatedQualityGate{qualityGate=QualityGate{id=id, name='name', conditions=[]}, status=ERROR, evaluatedConditions=[]}, updatedAt=1, properties={a=b}, analysis=Analysis{uuid='analysis_uuid', date=1500}}");
}
}
@Test
public void create_payload_for_successful_analysis() {
CeTask task = new CeTask("#1", CeTask.Status.SUCCESS);
- Condition condition = new Condition("coverage", Condition.Operator.GREATER_THAN, "70.0", "75.0");
+ Condition condition = new Condition("coverage", Condition.Operator.GREATER_THAN, "70.0");
EvaluatedQualityGate gate = EvaluatedQualityGate.newBuilder()
.setQualityGate(new QualityGate("G1", "Gate One", singleton(condition)))
- .setStatus(Metric.Level.WARN)
- .addCondition(condition, EvaluatedCondition.EvaluationStatus.WARN, "74.0")
+ .setStatus(Metric.Level.ERROR)
+ .addCondition(condition, EvaluatedCondition.EvaluationStatus.ERROR, "74.0")
.build();
ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, emptyMap());
" }," +
" \"qualityGate\": {" +
" \"name\": \"Gate One\"," +
- " \"status\": \"WARN\"," +
+ " \"status\": \"ERROR\"," +
" \"conditions\": [" +
" {" +
" \"metric\": \"coverage\"," +
" \"operator\": \"GREATER_THAN\"," +
" \"value\": \"74.0\"," +
- " \"status\": \"WARN\"," +
- " \"errorThreshold\": \"70.0\"," +
- " \"warningThreshold\": \"75.0\"" +
+ " \"status\": \"ERROR\"," +
+ " \"errorThreshold\": \"70.0\"" +
" }" +
" ]" +
" }," +
public void create_payload_with_gate_conditions_without_value() {
CeTask task = new CeTask("#1", CeTask.Status.SUCCESS);
- Condition condition = new Condition("coverage", Condition.Operator.GREATER_THAN, "70.0", "75.0");
+ Condition condition = new Condition("coverage", Condition.Operator.GREATER_THAN, "70.0");
EvaluatedQualityGate gate = EvaluatedQualityGate.newBuilder()
.setQualityGate(new QualityGate("G1", "Gate One", singleton(condition)))
- .setStatus(Metric.Level.WARN)
+ .setStatus(Metric.Level.ERROR)
.addCondition(condition, EvaluatedCondition.EvaluationStatus.NO_VALUE, null)
.build();
ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, emptyMap());
" }," +
" \"qualityGate\": {" +
" \"name\": \"Gate One\"," +
- " \"status\": \"WARN\"," +
+ " \"status\": \"ERROR\"," +
" \"conditions\": [" +
" {" +
" \"metric\": \"coverage\"," +
" \"operator\": \"GREATER_THAN\"," +
" \"status\": \"NO_VALUE\"," +
- " \"errorThreshold\": \"70.0\"," +
- " \"warningThreshold\": \"75.0\"" +
+ " \"errorThreshold\": \"70.0\"" +
" }" +
" ]" +
" }" +
CeTask task = new CeTask("#1", CeTask.Status.SUCCESS);
EvaluatedQualityGate gate = EvaluatedQualityGate.newBuilder()
.setQualityGate(new QualityGate("G1", "Gate One", emptySet()))
- .setStatus(Metric.Level.WARN)
+ .setStatus(Metric.Level.ERROR)
.build();
Map<String, String> scannerProperties = ImmutableMap.of(
"sonar.analysis.revision", "ab45d24",
" }," +
" \"qualityGate\": {" +
" \"name\": \"Gate One\"," +
- " \"status\": \"WARN\"," +
+ " \"status\": \"ERROR\"," +
" \"conditions\": [" +
" ]" +
" }," +
import static org.sonar.api.measures.Metric.Level;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
import static org.sonar.api.measures.Metric.ValueType;
import static org.sonar.server.badge.ws.ETagUtils.RFC1123_DATE;
import static org.sonar.server.badge.ws.ETagUtils.getETag;
private static final Map<Level, String> QUALITY_GATE_MESSAGE_BY_STATUS = new EnumMap<>(ImmutableMap.of(
OK, "passed",
- WARN, "warning",
ERROR, "failed"));
private static final Map<Level, Color> COLOR_BY_QUALITY_GATE_STATUS = new EnumMap<>(ImmutableMap.of(
OK, Color.QUALITY_GATE_OK,
- WARN, Color.QUALITY_GATE_WARN,
ERROR, Color.QUALITY_GATE_ERROR));
private static final Map<Rating, Color> COLOR_BY_RATING = new EnumMap<>(ImmutableMap.of(
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
import static org.sonar.process.ProcessProperties.Property.SONARCLOUD_ENABLED;
@ServerSide
this.badgeTemplate = readTemplate(templatePath + "/badge.svg");
this.qualityGateTemplates = ImmutableMap.of(
OK, readTemplate(templatePath + "/quality_gate_passed.svg"),
- WARN, readTemplate(templatePath + "/quality_gate_warn.svg"),
ERROR, readTemplate(templatePath + "/quality_gate_failed.svg"));
}
static class Color {
static final Color DEFAULT = new Color("#999");
static final Color QUALITY_GATE_OK = new Color("#4c1");
- static final Color QUALITY_GATE_WARN = new Color("#ed7d20");
static final Color QUALITY_GATE_ERROR = new Color("#d4333f");
static final Color RATING_A = new Color("#00aa00");
static final Color RATING_B = new Color("#b0d513");
Set<Condition> conditions = conditionDtos.stream().map(conditionDto -> {
String metricKey = metricsById.get((int) conditionDto.getMetricId()).getKey();
Condition.Operator operator = Condition.Operator.fromDbValue(conditionDto.getOperator());
- return new Condition(metricKey, operator, conditionDto.getErrorThreshold(), conditionDto.getWarningThreshold());
+ return new Condition(metricKey, operator, conditionDto.getErrorThreshold());
}).collect(toHashSet(conditionDtos.size()));
return new QualityGate(String.valueOf(gateDto.getId()), gateDto.getName(), conditions);
import static java.lang.Long.parseLong;
import static java.lang.String.format;
import static java.util.Arrays.stream;
+import static java.util.Objects.requireNonNull;
import static org.sonar.api.measures.Metric.ValueType.RATING;
import static org.sonar.api.measures.Metric.ValueType.valueOf;
import static org.sonar.db.qualitygate.QualityGateConditionDto.isOperatorAllowed;
}
public QualityGateConditionDto createCondition(DbSession dbSession, QualityGateDto qualityGate, String metricKey, String operator,
- @Nullable String warningThreshold, @Nullable String errorThreshold) {
+ String errorThreshold) {
MetricDto metric = getNonNullMetric(dbSession, metricKey);
- validateCondition(metric, operator, warningThreshold, errorThreshold);
+ validateCondition(metric, operator, errorThreshold);
checkConditionDoesNotExistOnSameMetric(getConditions(dbSession, qualityGate.getId()), metric);
QualityGateConditionDto newCondition = new QualityGateConditionDto().setQualityGateId(qualityGate.getId())
.setMetricId(metric.getId()).setMetricKey(metric.getKey())
.setOperator(operator)
- .setWarningThreshold(warningThreshold)
.setErrorThreshold(errorThreshold);
dbClient.gateConditionDao().insert(newCondition, dbSession);
return newCondition;
}
public QualityGateConditionDto updateCondition(DbSession dbSession, QualityGateConditionDto condition, String metricKey, String operator,
- @Nullable String warningThreshold, @Nullable String errorThreshold) {
+ String errorThreshold) {
MetricDto metric = getNonNullMetric(dbSession, metricKey);
- validateCondition(metric, operator, warningThreshold, errorThreshold);
+ validateCondition(metric, operator, errorThreshold);
condition
.setMetricId(metric.getId())
.setMetricKey(metric.getKey())
.setOperator(operator)
- .setWarningThreshold(warningThreshold)
.setErrorThreshold(errorThreshold);
dbClient.gateConditionDao().update(condition, dbSession);
return condition;
return dbClient.gateConditionDao().selectForQualityGate(dbSession, qGateId);
}
- private static void validateCondition(MetricDto metric, String operator, @Nullable String warningThreshold, @Nullable String errorThreshold) {
+ private static void validateCondition(MetricDto metric, String operator, String errorThreshold) {
List<String> errors = new ArrayList<>();
validateMetric(metric, errors);
checkOperator(metric, operator, errors);
- checkThresholds(warningThreshold, errorThreshold, errors);
-
- validateThresholdValues(metric, warningThreshold, errors);
- validateThresholdValues(metric, errorThreshold, errors);
- checkRatingMetric(metric, warningThreshold, errorThreshold, errors);
+ checkErrorThreshold(metric, errorThreshold, errors);
+ checkRatingMetric(metric, errorThreshold, errors);
checkRequest(errors.isEmpty(), errors);
}
check(isOperatorAllowed(operator, valueType), errors, "Operator %s is not allowed for metric type %s.", operator, metric.getValueType());
}
- private static void checkThresholds(@Nullable String warningThreshold, @Nullable String errorThreshold, List<String> errors) {
- check(warningThreshold != null || errorThreshold != null, errors, "At least one threshold (warning, error) must be set.");
+ private static void checkErrorThreshold(MetricDto metric, String errorThreshold, List<String> errors) {
+ requireNonNull(errorThreshold, "errorThreshold can not be null");
+ validateErrorThresholdValue(metric, errorThreshold, errors);
}
private static void checkConditionDoesNotExistOnSameMetric(Collection<QualityGateConditionDto> conditions, MetricDto metric) {
checkRequest(!conditionExists, format("Condition on metric '%s' already exists.", metric.getShortName()));
}
- private static void validateThresholdValues(MetricDto metric, @Nullable String value, List<String> errors) {
- if (value == null) {
- return;
- }
+ private static void validateErrorThresholdValue(MetricDto metric, String errorThreshold, List<String> errors) {
try {
ValueType valueType = ValueType.valueOf(metric.getValueType());
switch (valueType) {
case BOOL:
case INT:
case RATING:
- parseInt(value);
+ parseInt(errorThreshold);
return;
case MILLISEC:
case WORK_DUR:
- parseLong(value);
+ parseLong(errorThreshold);
return;
case FLOAT:
case PERCENT:
- parseDouble(value);
+ parseDouble(errorThreshold);
return;
case STRING:
case LEVEL:
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()));
+ errors.add(format("Invalid value '%s' for metric '%s'", errorThreshold, metric.getShortName()));
}
}
- private static void checkRatingMetric(MetricDto metric, @Nullable String warningThreshold, @Nullable String errorThreshold, List<String> errors) {
+ private static void checkRatingMetric(MetricDto metric, String errorThreshold, List<String> errors) {
if (!metric.getValueType().equals(RATING.name())) {
return;
}
if (!isCoreRatingMetric(metric.getKey())) {
errors.add(format("The metric '%s' cannot be used", metric.getShortName()));
}
- if (!isValidRating(warningThreshold)) {
- addInvalidRatingError(warningThreshold, errors);
- return;
- }
if (!isValidRating(errorThreshold)) {
addInvalidRatingError(errorThreshold, errors);
return;
}
- checkRatingGreaterThanOperator(warningThreshold, errors);
checkRatingGreaterThanOperator(errorThreshold, errors);
}
JsonObject result = new JsonObject();
result.addProperty("metric", condition.getMetricKey());
result.addProperty("op", condition.getOperator().getDbValue());
- condition.getWarningThreshold().ifPresent(t -> result.addProperty("warning", t));
- condition.getErrorThreshold().ifPresent(t -> result.addProperty("error", t));
+ result.addProperty("error", condition.getErrorThreshold());
evaluatedCondition.getValue().ifPresent(v -> result.addProperty("actual", v));
result.addProperty(FIELD_LEVEL, evaluatedCondition.getStatus().name());
return result;
QualityGateDto destinationGate = create(dbSession, organizationDto, destinationName);
for (QualityGateConditionDto sourceCondition : dbClient.gateConditionDao().selectForQualityGate(dbSession, qualityGateDto.getId())) {
- dbClient.gateConditionDao().insert(new QualityGateConditionDto().setQualityGateId(destinationGate.getId())
- .setMetricId(sourceCondition.getMetricId()).setOperator(sourceCondition.getOperator())
- .setWarningThreshold(sourceCondition.getWarningThreshold()).setErrorThreshold(sourceCondition.getErrorThreshold()),
+ dbClient.gateConditionDao().insert(new QualityGateConditionDto()
+ .setQualityGateId(destinationGate.getId())
+ .setMetricId(sourceCondition.getMetricId())
+ .setOperator(sourceCondition.getOperator())
+ .setErrorThreshold(sourceCondition.getErrorThreshold()),
dbSession);
}
import java.util.Map;
import java.util.Objects;
import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
import org.picocontainer.Startable;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.Logger;
List<QualityGateCondition> qgConditionsToBeCreated = new ArrayList<>(QUALITY_GATE_CONDITIONS);
qgConditionsToBeCreated.removeAll(qualityGateConditions);
qgConditionsToBeCreated
- .forEach(qgc -> qualityGateConditionsUpdater.createCondition(dbSession, builtin, qgc.getMetricKey(), qgc.getOperator(), qgc.getWarningThreshold(),
+ .forEach(qgc -> qualityGateConditionsUpdater.createCondition(dbSession, builtin, qgc.getMetricKey(), qgc.getOperator(),
qgc.getErrorThreshold()));
if (!qgConditionsToBeCreated.isEmpty() || !qgConditionsToBeDeleted.isEmpty()) {
private Long id;
private String metricKey;
private String operator;
- private String warningThreshold;
private String errorThreshold;
public static QualityGateCondition from(QualityGateConditionDto qualityGateConditionDto, Map<Long, String> mapping) {
.setId(qualityGateConditionDto.getId())
.setMetricKey(mapping.get(qualityGateConditionDto.getMetricId()))
.setOperator(qualityGateConditionDto.getOperator())
- .setErrorThreshold(qualityGateConditionDto.getErrorThreshold())
- .setWarningThreshold(qualityGateConditionDto.getWarningThreshold());
+ .setErrorThreshold(qualityGateConditionDto.getErrorThreshold());
}
@CheckForNull
return this;
}
- @CheckForNull
- public String getWarningThreshold() {
- return warningThreshold;
- }
-
- public QualityGateCondition setWarningThreshold(@Nullable String warningThreshold) {
- this.warningThreshold = warningThreshold;
- return this;
- }
-
- @CheckForNull
public String getErrorThreshold() {
return errorThreshold;
}
- public QualityGateCondition setErrorThreshold(@Nullable String errorThreshold) {
+ public QualityGateCondition setErrorThreshold(String errorThreshold) {
this.errorThreshold = errorThreshold;
return this;
}
.setMetricKey(metricKey)
.setOperator(operator)
.setErrorThreshold(errorThreshold)
- .setWarningThreshold(warningThreshold)
.setQualityGateId(qualityGateId);
}
QualityGateCondition that = (QualityGateCondition) o;
return Objects.equals(metricKey, that.metricKey) &&
Objects.equals(operator, that.operator) &&
- Objects.equals(warningThreshold, that.warningThreshold) &&
Objects.equals(errorThreshold, that.errorThreshold);
}
// id does not belongs to hashcode to be able to be compared with builtin
@Override
public int hashCode() {
- return Objects.hash(metricKey, operator, warningThreshold, errorThreshold);
+ return Objects.hash(metricKey, operator, errorThreshold);
}
}
}
*/
package org.sonar.server.qualitygate.ws;
+import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_ID;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_METRIC;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_OPERATOR;
-import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_WARNING;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
public class CreateConditionAction implements QualityGatesWsAction {
"Requires the 'Administer Quality Gates' permission.")
.setSince("4.3")
.setResponseExample(getClass().getResource("create-condition-example.json"))
+ .setChangelog(
+ new Change("7.6", "Removed optional 'warning' and 'period' parameters"),
+ new Change("7.6", "Made 'error' parameter mandatory"),
+ new Change("7.6", "Reduced the possible values of 'op' parameter to LT and GT"))
.setHandler(this);
createCondition
int gateId = request.mandatoryParamAsInt(PARAM_GATE_ID);
String metric = request.mandatoryParam(PARAM_METRIC);
String operator = request.mandatoryParam(PARAM_OPERATOR);
- String warning = request.param(PARAM_WARNING);
- String error = request.param(PARAM_ERROR);
+ String error = request.mandatoryParam(PARAM_ERROR);
try (DbSession dbSession = dbClient.openSession(false)) {
OrganizationDto organization = wsSupport.getOrganization(dbSession, request);
QGateWithOrgDto qualityGate = wsSupport.getByOrganizationAndId(dbSession, organization, gateId);
wsSupport.checkCanEdit(qualityGate);
- QualityGateConditionDto condition = qualityGateConditionsUpdater.createCondition(dbSession, qualityGate, metric, operator, emptyToNull(warning), emptyToNull(error));
+ QualityGateConditionDto condition = qualityGateConditionsUpdater.createCondition(dbSession, qualityGate, metric, operator, error);
CreateConditionResponse.Builder createConditionResponse = CreateConditionResponse.newBuilder()
.setId(condition.getId())
.setMetric(condition.getMetricKey())
+ .setError(condition.getErrorThreshold())
.setOp(condition.getOperator());
- setNullable(condition.getWarningThreshold(), createConditionResponse::setWarning);
- setNullable(condition.getErrorThreshold(), createConditionResponse::setError);
writeProtobuf(createConditionResponse.build(), request, response);
dbSession.commit();
}
.setSince("5.3")
.setHandler(this)
.setChangelog(
+ new Change("7.6", "The field 'warning' is deprecated from the response"),
new Change("6.4", "The field 'ignoredConditions' is added to the response"));
action.createParam(PARAM_ANALYSIS_ID)
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ERROR;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_METRIC;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_OPERATOR;
-import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_WARNING;
+
public class QualityGatesWs implements WebService {
.setExampleValue(QualityGateConditionDto.OPERATOR_EQUALS)
.setPossibleValues(QualityGateConditionDto.ALL_OPERATORS);
- action.createParam(PARAM_WARNING)
- .setMaximumLength(CONDITION_MAX_LENGTH)
- .setDescription("Condition warning threshold")
- .setExampleValue("5");
-
action.createParam(PARAM_ERROR)
.setMaximumLength(CONDITION_MAX_LENGTH)
.setDescription("Condition error threshold")
+ .setRequired(true)
.setExampleValue("10");
}
public static final String PARAM_QUERY = "query";
public static final String PARAM_NAME = "name";
public static final String PARAM_ERROR = "error";
- public static final String PARAM_WARNING = "warning";
public static final String PARAM_OPERATOR = "op";
public static final String PARAM_METRIC = "metric";
public static final String PARAM_GATE_ID = "gateId";
.setSince("4.3")
.setResponseExample(Resources.getResource(this.getClass(), "show-example.json"))
.setChangelog(
+ new Change("7.6", "'period' and 'warning' fields of conditions are removed from the response"),
new Change("7.0", "'isBuiltIn' field is added to the response"),
new Change("7.0", "'actions' field is added in the response"))
.setHandler(this);
.setMetric(metric.getKey())
.setOp(condition.getOperator());
setNullable(condition.getErrorThreshold(), builder::setError);
- setNullable(condition.getWarningThreshold(), builder::setWarning);
return builder.build();
};
}
*/
package org.sonar.server.qualitygate.ws;
+import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ID;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_METRIC;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_OPERATOR;
-import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_WARNING;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
public class UpdateConditionAction implements QualityGatesWsAction {
"Requires the 'Administer Quality Gates' permission.")
.setPost(true)
.setSince("4.3")
+ .setChangelog(
+ new Change("7.6", "Removed optional 'warning' and 'period' parameters"),
+ new Change("7.6", "Made 'error' parameter mandatory"),
+ new Change("7.6", "Reduced the possible values of 'op' parameter to LT and GT"))
.setHandler(this);
createCondition
int id = request.mandatoryParamAsInt(PARAM_ID);
String metric = request.mandatoryParam(PARAM_METRIC);
String operator = request.mandatoryParam(PARAM_OPERATOR);
- String warning = request.param(PARAM_WARNING);
- String error = request.param(PARAM_ERROR);
+ String error = request.mandatoryParam(PARAM_ERROR);
try (DbSession dbSession = dbClient.openSession(false)) {
OrganizationDto organization = wsSupport.getOrganization(dbSession, request);
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,
- emptyToNull(warning), emptyToNull(error));
+ QualityGateConditionDto updatedCondition = qualityGateConditionsUpdater.updateCondition(dbSession, condition, metric, operator, error);
UpdateConditionResponse.Builder updateConditionResponse = UpdateConditionResponse.newBuilder()
.setId(updatedCondition.getId())
.setMetric(updatedCondition.getMetricKey())
+ .setError(updatedCondition.getErrorThreshold())
.setOp(updatedCondition.getOperator());
- setNullable(updatedCondition.getWarningThreshold(), updateConditionResponse::setWarning);
- setNullable(updatedCondition.getErrorThreshold(), updateConditionResponse::setError);
writeProtobuf(updateConditionResponse.build(), request, response);
dbSession.commit();
}
try {
Metric.Level.valueOf(value);
} catch (IllegalArgumentException e) {
- throw BadRequestException.create(format("Value '%s' must be one of \"OK\", \"WARN\", \"ERROR\".", value));
+ throw BadRequestException.create(format("Value '%s' must be one of \"OK\", \"ERROR\".", value));
}
}
}
"metricKey": "reopened_issues",
"comparator": "GT",
"periodIndex": 1,
- "warningThreshold": "0",
"actualValue": "0"
},
{
- "status": "WARN",
+ "status": "ERROR",
"metricKey": "open_issues",
"comparator": "GT",
"periodIndex": 1,
- "warningThreshold": "0",
"actualValue": "17"
},
{
"metricKey": "skipped_tests",
"comparator": "GT",
"periodIndex": 1,
- "warningThreshold": "0",
"actualValue": "0"
}
],
},
{
"id": 3,
- "metric": "critical_violations",
+ "metric": "tests",
"op": "LT",
- "warning": "0"
+ "error": "10"
}
],
"isBuiltIn": false,
import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
import static org.sonar.api.measures.Metric.ValueType.INT;
import static org.sonar.api.measures.Metric.ValueType.LEVEL;
import static org.sonar.api.measures.Metric.ValueType.PERCENT;
import static org.sonar.server.badge.ws.SvgGenerator.Color.DEFAULT;
import static org.sonar.server.badge.ws.SvgGenerator.Color.QUALITY_GATE_ERROR;
import static org.sonar.server.badge.ws.SvgGenerator.Color.QUALITY_GATE_OK;
-import static org.sonar.server.badge.ws.SvgGenerator.Color.QUALITY_GATE_WARN;
@RunWith(DataProviderRunner.class)
public class MeasureActionTest {
public static Object[][] qualityGates() {
return new Object[][] {
{OK, "passed", QUALITY_GATE_OK},
- {WARN, "warning", QUALITY_GATE_WARN},
{ERROR, "failed", QUALITY_GATE_ERROR}
};
}
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
import static org.sonar.api.measures.Metric.ValueType.LEVEL;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.db.component.BranchType.LONG;
checkResponse(response, OK);
}
- @Test
- public void quality_gate_warn() {
- ComponentDto project = db.components().insertPublicProject();
- userSession.registerComponents(project);
- MetricDto metric = createQualityGateMetric();
- db.measures().insertLiveMeasure(project, metric, m -> m.setData(WARN.name()));
-
- TestResponse response = ws.newRequest()
- .setParam("project", project.getKey())
- .execute();
-
- checkResponse(response, WARN);
- }
-
@Test
public void quality_gate_failed() {
ComponentDto project = db.components().insertPublicProject();
.execute();
String eTagOK = response.getHeader("ETag");
- liveMeasure.setData(WARN.name());
- db.getDbClient().liveMeasureDao().insertOrUpdate(db.getSession(), liveMeasure);
- db.commit();
-
- response = ws.newRequest()
- .setParam("project", project.getKey())
- .execute();
-
- String eTagWARN = response.getHeader("ETag");
-
liveMeasure.setData(ERROR.name());
db.getDbClient().liveMeasureDao().insertOrUpdate(db.getSession(), liveMeasure);
db.commit();
String eTagERROR = response.getHeader("ETag");
- assertThat(Arrays.asList(eTagOK, eTagWARN, eTagERROR))
+ assertThat(Arrays.asList(eTagOK, eTagERROR))
.doesNotContainNull()
.doesNotHaveDuplicates();
}
MetricDto metric = createQualityGateMetric();
db.measures().insertLiveMeasure(project, metric, m -> m.setData(OK.name()));
ComponentDto longBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(LONG));
- db.measures().insertLiveMeasure(longBranch, metric, m -> m.setData(WARN.name()));
+ db.measures().insertLiveMeasure(longBranch, metric, m -> m.setData(ERROR.name()));
TestResponse response = ws.newRequest()
.setParam("project", longBranch.getKey())
.setParam("branch", longBranch.getBranch())
.execute();
- checkResponse(response, WARN);
+ checkResponse(response, ERROR);
}
@Test
ComponentDto application = db.components().insertPublicApplication(organization);
userSession.registerComponents(application);
MetricDto metric = createQualityGateMetric();
- db.measures().insertLiveMeasure(application, metric, m -> m.setData(WARN.name()));
+ db.measures().insertLiveMeasure(application, metric, m -> m.setData(ERROR.name()));
TestResponse response = ws.newRequest()
.setParam("project", application.getKey())
.execute();
- checkResponse(response, WARN);
+ checkResponse(response, ERROR);
}
@Test
case OK:
assertThat(response.getInput()).contains("<!-- SONARQUBE QUALITY GATE PASS -->");
break;
- case WARN:
- assertThat(response.getInput()).contains("<!-- SONARQUBE QUALITY GATE WARN -->");
- break;
case ERROR:
assertThat(response.getInput()).contains("<!-- SONARQUBE QUALITY GATE FAIL -->");
break;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.api.measures.Metric.Level.WARN;
+import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.server.badge.ws.SvgGenerator.Color.DEFAULT;
public class SvgGeneratorTest {
mapSettings.setProperty("sonar.sonarcloud.enabled", false);
initSvgGenerator();
- String result = underTest.generateQualityGate(WARN);
+ String result = underTest.generateQualityGate(ERROR);
- checkQualityGate(result, WARN);
+ checkQualityGate(result, ERROR);
}
@Test
case OK:
assertThat(response).isEqualTo(readTemplate("quality_gate_passed.svg"));
break;
- case WARN:
- assertThat(response).isEqualTo(readTemplate("quality_gate_warn.svg"));
- break;
case ERROR:
assertThat(response).isEqualTo(readTemplate("quality_gate_failed.svg"));
break;
OrganizationDto organization = db.organizations().insert();
MetricDto qualityGateStatus = db.measures().insertMetric(c -> c.setKey(QUALITY_GATE_STATUS).setValueType(LEVEL.name()));
ComponentDto project1 = insertProject(organization, c -> c.setName("Sonar Java"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("ERROR")));
- ComponentDto project2 = insertProject(organization, c -> c.setName("Sonar Groovy"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("WARN")));
+ ComponentDto project2 = insertProject(organization, c -> c.setName("Sonar Groovy"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("ERROR")));
ComponentDto project3 = insertProject(organization, c -> c.setName("Sonar Markdown"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("OK")));
ComponentDto project4 = insertProject(organization, c -> c.setName("Sonar Qube"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("OK")));
assertThat(call(request.setSort(QUALITY_GATE_STATUS).setAsc(true)).getComponentsList()).extracting(Component::getKey)
.containsExactly(project3.getDbKey(), project4.getDbKey(), project2.getDbKey(), project1.getDbKey());
assertThat(call(request.setSort(QUALITY_GATE_STATUS).setAsc(false)).getComponentsList()).extracting(Component::getKey)
- .containsExactly(project1.getDbKey(), project2.getDbKey(), project3.getDbKey(), project4.getDbKey());
+ .containsExactly(project2.getDbKey(), project1.getDbKey(), project3.getDbKey(), project4.getDbKey());
}
@Test
ws.newRequest()
.setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
.setParam(CreateAction.PARAM_METRIC_ID, metric.getId().toString())
- .setParam(CreateAction.PARAM_VALUE, Metric.Level.WARN.name())
+ .setParam(CreateAction.PARAM_VALUE, Metric.Level.ERROR.name())
.execute();
assertThat(db.getDbClient().customMeasureDao().selectByMetricId(db.getSession(), metric.getId()))
.extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple(null, Metric.Level.WARN.name(), 0d, project.uuid()));
+ .containsExactlyInAnyOrder(tuple(null, Metric.Level.ERROR.name(), 0d, project.uuid()));
}
@Test
import org.sonar.db.measure.custom.CustomMeasureTesting;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.api.measures.Metric.Level.WARN;
+import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.ValueType.BOOL;
import static org.sonar.api.measures.Metric.ValueType.FLOAT;
import static org.sonar.api.measures.Metric.ValueType.INT;
@Test
public void set_level_value() {
- underTest.setMeasureValue(customMeasure, WARN.name(), newMetricDto().setValueType(LEVEL.name()));
+ underTest.setMeasureValue(customMeasure, ERROR.name(), newMetricDto().setValueType(LEVEL.name()));
- assertThat(customMeasure.getTextValue()).isEqualTo(WARN.name());
+ assertThat(customMeasure.getTextValue()).isEqualTo(ERROR.name());
}
@Test
import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.user.GroupTesting.newGroupDto;
index(
newDoc(PROJECT1).setQualityGateStatus(OK.name()),
newDoc(PROJECT2).setQualityGateStatus(ERROR.name()),
- newDoc(PROJECT3).setQualityGateStatus(WARN.name()),
newDoc(project4).setQualityGateStatus(OK.name()));
- assertResults(new ProjectMeasuresQuery().setSort("alert_status").setAsc(true), PROJECT1, project4, PROJECT3, PROJECT2);
- assertResults(new ProjectMeasuresQuery().setSort("alert_status").setAsc(false), PROJECT2, PROJECT3, PROJECT1, project4);
+ assertResults(new ProjectMeasuresQuery().setSort("alert_status").setAsc(true), PROJECT1, project4, PROJECT2);
+ assertResults(new ProjectMeasuresQuery().setSort("alert_status").setAsc(false), PROJECT2, PROJECT1, project4);
}
@Test
ComponentDto apache1 = ComponentTesting.newPrivateProjectDto(ORG).setUuid("apache-1").setName("Apache").setDbKey("project3");
ComponentDto apache2 = ComponentTesting.newPrivateProjectDto(ORG).setUuid("apache-2").setName("Apache").setDbKey("project4");
index(
- newDoc(windows).setQualityGateStatus(WARN.name()),
+ newDoc(windows).setQualityGateStatus(ERROR.name()),
newDoc(apachee).setQualityGateStatus(OK.name()),
newDoc(apache1).setQualityGateStatus(OK.name()),
newDoc(apache2).setQualityGateStatus(OK.name()));
index(
newDoc(PROJECT1).setQualityGateStatus(OK.name()),
newDoc(PROJECT2).setQualityGateStatus(OK.name()),
- newDoc(PROJECT3).setQualityGateStatus(WARN.name()));
+ newDoc(PROJECT3).setQualityGateStatus(ERROR.name()));
ProjectMeasuresQuery query = new ProjectMeasuresQuery().setQualityGateStatus(OK);
assertResults(query, PROJECT1, PROJECT2);
// 2 docs with QG OK
newDoc().setQualityGateStatus(OK.name()),
newDoc().setQualityGateStatus(OK.name()),
- // 3 docs with QG WARN
- newDoc().setQualityGateStatus(WARN.name()),
- newDoc().setQualityGateStatus(WARN.name()),
- newDoc().setQualityGateStatus(WARN.name()),
// 4 docs with QG ERROR
newDoc().setQualityGateStatus(ERROR.name()),
newDoc().setQualityGateStatus(ERROR.name()),
assertThat(result).containsOnly(
entry(ERROR.name(), 4L),
- entry(WARN.name(), 3L),
entry(OK.name(), 2L));
}
// 2 docs with QG OK
newDoc(NCLOC, 10d, COVERAGE, 0d).setQualityGateStatus(OK.name()),
newDoc(NCLOC, 10d, COVERAGE, 0d).setQualityGateStatus(OK.name()),
- // 3 docs with QG WARN
- newDoc(NCLOC, 100d, COVERAGE, 0d).setQualityGateStatus(WARN.name()),
- newDoc(NCLOC, 100d, COVERAGE, 0d).setQualityGateStatus(WARN.name()),
- newDoc(NCLOC, 100d, COVERAGE, 0d).setQualityGateStatus(WARN.name()),
// 4 docs with QG ERROR
newDoc(NCLOC, 100d, COVERAGE, 0d).setQualityGateStatus(ERROR.name()),
newDoc(NCLOC, 5000d, COVERAGE, 40d).setQualityGateStatus(ERROR.name()),
// Sticky facet on quality gate does not take into account quality gate filter
assertThat(facets.get(ALERT_STATUS_KEY)).containsOnly(
entry(OK.name(), 2L),
- entry(WARN.name(), 3L),
entry(ERROR.name(), 3L));
// But facet on ncloc does well take into into filters
assertThat(facets.get(NCLOC)).containsExactly(
indexForUser(USER1,
// 2 docs with QG OK
newDoc().setQualityGateStatus(OK.name()),
- newDoc().setQualityGateStatus(OK.name()),
- // 3 docs with QG WARN
- newDoc().setQualityGateStatus(WARN.name()),
- newDoc().setQualityGateStatus(WARN.name()),
- newDoc().setQualityGateStatus(WARN.name()));
+ newDoc().setQualityGateStatus(OK.name()));
// User cannot see these projects
indexForUser(USER2,
assertThat(result).containsOnly(
entry(ERROR.name(), 0L),
- entry(WARN.name(), 3L),
entry(OK.name(), 2L));
}
index(
newDoc().setTags(newArrayList("finance")).setQualityGateStatus(OK.name()),
newDoc().setTags(newArrayList("finance")).setQualityGateStatus(ERROR.name()),
- newDoc().setTags(newArrayList("cpp")).setQualityGateStatus(WARN.name()));
+ newDoc().setTags(newArrayList("cpp")).setQualityGateStatus(ERROR.name()));
Facets facets = underTest.search(
new ProjectMeasuresQuery().setTags(newHashSet("cpp")),
entry("cpp", 1L));
assertThat(facets.get(ALERT_STATUS_KEY)).containsOnly(
entry(OK.name(), 0L),
- entry(ERROR.name(), 0L),
- entry(WARN.name(), 1L));
+ entry(ERROR.name(), 1L));
}
@Test
@Test
public void event_contains_newQualityGate_computed_by_LiveQualityGateComputer() {
markProjectAsAnalyzed(project);
- db.measures().insertLiveMeasure(project, alertStatusMetric, m -> m.setData(Metric.Level.WARN.name()));
+ db.measures().insertLiveMeasure(project, alertStatusMetric, m -> m.setData(Metric.Level.ERROR.name()));
db.measures().insertLiveMeasure(project, intMetric, m -> m.setVariation(42.0).setValue(null));
BranchDto branch = db.getDbClient().branchDao().selectByBranchKey(db.getSession(), project.projectUuid(), "master")
.orElseThrow(() -> new IllegalStateException("Can't find master branch"));
assertThat(result.getId()).isEqualTo("" + gate.getId());
assertThat(result.getConditions())
- .extracting(Condition::getMetricKey, Condition::getOperator, c -> c.getErrorThreshold().get(), c -> c.getWarningThreshold().get())
+ .extracting(Condition::getMetricKey, Condition::getOperator, Condition::getErrorThreshold)
.containsExactlyInAnyOrder(
- tuple(metric.getKey(), Condition.Operator.fromDbValue(condition.getOperator()), condition.getErrorThreshold(), condition.getWarningThreshold()));
+ tuple(metric.getKey(), Condition.Operator.fromDbValue(condition.getOperator()), condition.getErrorThreshold()));
}
@Test
public void getMetricsRelatedTo() {
- Condition condition = new Condition("metric1", Condition.Operator.EQUALS, "10", null);
+ Condition condition = new Condition("metric1", Condition.Operator.EQUALS, "10");
QualityGate gate = new QualityGate("1", "foo", ImmutableSet.of(condition));
Set<String> result = underTest.getMetricsRelatedTo(gate);
MetricDto conditionMetric = newMetricDto();
MetricDto statusMetric = newMetricDto().setKey(CoreMetrics.ALERT_STATUS_KEY);
MetricDto detailsMetric = newMetricDto().setKey(CoreMetrics.QUALITY_GATE_DETAILS_KEY);
- Condition condition = new Condition(conditionMetric.getKey(), Condition.Operator.GREATER_THAN, "10", null);
+ Condition condition = new Condition(conditionMetric.getKey(), Condition.Operator.GREATER_THAN, "10");
QualityGate gate = new QualityGate("1", "foo", ImmutableSet.of(condition));
MeasureMatrix matrix = new MeasureMatrix(singleton(project), asList(conditionMetric, statusMetric, detailsMetric), emptyList());
public void sort_by_alert_status_ascending() {
components = newArrayList(
newComponentWithoutSnapshotId("PROJECT OK 1", Qualifiers.PROJECT, "PROJECT_OK_PATH_1"),
- newComponentWithoutSnapshotId("PROJECT WARN 1", Qualifiers.PROJECT, "PROJECT_WARN_PATH_1"),
newComponentWithoutSnapshotId("PROJECT ERROR 1", Qualifiers.PROJECT, "PROJECT_ERROR_PATH_1"),
newComponentWithoutSnapshotId("PROJECT OK 2", Qualifiers.PROJECT, "PROJECT_OK_PATH_2"),
- newComponentWithoutSnapshotId("PROJECT WARN 2", Qualifiers.PROJECT, "PROJECT_WARN_PATH_2"),
newComponentWithoutSnapshotId("PROJECT ERROR 2", Qualifiers.PROJECT, "PROJECT_ERROR_PATH_2"));
metrics = singletonList(newMetricDto()
.setKey(CoreMetrics.ALERT_STATUS_KEY)
.setValueType(ValueType.LEVEL.name()));
measuresByComponentUuidAndMetric = HashBasedTable.create();
- List<String> statuses = newArrayList("OK", "WARN", "ERROR");
+ List<String> statuses = newArrayList("OK", "ERROR");
for (int i = 0; i < components.size(); i++) {
ComponentDto component = components.get(i);
- String alertStatus = statuses.get(i % 3);
+ String alertStatus = statuses.get(i % 2);
measuresByComponentUuidAndMetric.put(component.uuid(), metrics.get(0), createFromMeasureDto(new LiveMeasureDto().setData(alertStatus)));
}
ComponentTreeRequest wsRequest = newRequest(newArrayList(METRIC_SORT, NAME_SORT), true, CoreMetrics.ALERT_STATUS_KEY);
assertThat(result).extracting("name").containsExactly(
"PROJECT ERROR 1", "PROJECT ERROR 2",
- "PROJECT WARN 1", "PROJECT WARN 2",
"PROJECT OK 1", "PROJECT OK 2");
}
@Test
public void shouldFormatAlertWithSeveralMessages() {
- Notification notification = createNotification("Orange (was Red)", "violations > 4, coverage < 75%", "WARN", "false");
+ Notification notification = createNotification("Red (was Green)", "violations > 4, coverage < 75%", "ERROR", "false");
EmailMessage message = template.format(notification);
assertThat(message.getMessageId(), is("alerts/45"));
assertThat(message.getMessage(), is("" +
"Project: Foo\n" +
"Version: V1-SNAP\n" +
- "Quality gate status: Orange (was Red)\n" +
+ "Quality gate status: Red (was Green)\n" +
"\n" +
"Quality gate thresholds:\n" +
" - violations > 4\n" +
@Test
public void shouldFormatAlertWithSeveralMessagesOnBranch() {
- Notification notification = createNotification("Orange (was Red)", "violations > 4, coverage < 75%", "WARN", "false")
+ Notification notification = createNotification("Red (was Green)", "violations > 4, coverage < 75%", "ERROR", "false")
.setFieldValue("branch", "feature");
EmailMessage message = template.format(notification);
"Project: Foo\n" +
"Branch: feature\n" +
"Version: V1-SNAP\n" +
- "Quality gate status: Orange (was Red)\n" +
+ "Quality gate status: Red (was Green)\n" +
"\n" +
"Quality gate thresholds:\n" +
" - violations > 4\n" +
@Test
public void shouldFormatNewAlertWithSeveralMessages() {
- Notification notification = createNotification("Orange (was Red)", "violations > 4, coverage < 75%", "WARN", "true");
+ Notification notification = createNotification("Red (was Green)", "violations > 4, coverage < 75%", "ERROR", "true");
EmailMessage message = template.format(notification);
assertThat(message.getMessageId(), is("alerts/45"));
assertThat(message.getMessage(), is("" +
"Project: Foo\n" +
"Version: V1-SNAP\n" +
- "Quality gate status: Orange (was Red)\n" +
+ "Quality gate status: Red (was Green)\n" +
"\n" +
"New quality gate thresholds:\n" +
" - violations > 4\n" +
@Test
public void shouldFormatNewAlertWithOneMessage() {
- Notification notification = createNotification("Orange (was Red)", "violations > 4", "WARN", "true");
+ Notification notification = createNotification("Red (was Green)", "violations > 4", "ERROR", "true");
EmailMessage message = template.format(notification);
assertThat(message.getMessageId(), is("alerts/45"));
assertThat(message.getMessage(), is("" +
"Project: Foo\n" +
"Version: V1-SNAP\n" +
- "Quality gate status: Orange (was Red)\n" +
+ "Quality gate status: Red (was Green)\n" +
"\n" +
"New quality gate threshold: violations > 4\n" +
"\n" +
@Test
public void shouldFormatNewAlertWithoutVersion() {
- Notification notification = createNotification("Orange (was Red)", "violations > 4", "WARN", "true")
+ Notification notification = createNotification("Red (was Green)", "violations > 4", "ERROR", "true")
.setFieldValue("projectVersion", null);
EmailMessage message = template.format(notification);
assertThat(message.getSubject(), is("New quality gate threshold reached on \"Foo\""));
assertThat(message.getMessage(), is("" +
"Project: Foo\n" +
- "Quality gate status: Orange (was Red)\n" +
+ "Quality gate status: Red (was Green)\n" +
"\n" +
"New quality gate threshold: violations > 4\n" +
"\n" +
@Test
public void shouldFormatNewAlertWithOneMessageOnBranch() {
- Notification notification = createNotification("Orange (was Red)", "violations > 4", "WARN", "true")
+ Notification notification = createNotification("Red (was Green)", "violations > 4", "ERROR", "true")
.setFieldValue("branch", "feature");
EmailMessage message = template.format(notification);
"Project: Foo\n" +
"Branch: feature\n" +
"Version: V1-SNAP\n" +
- "Quality gate status: Orange (was Red)\n" +
+ "Quality gate status: Red (was Green)\n" +
"\n" +
"New quality gate threshold: violations > 4\n" +
"\n" +
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(db.getSession(), qualityGate, metric.getKey(), "LT", null, "80");
+ QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "80");
- verifyCondition(result, qualityGate, metric, "LT", null, "80");
+ verifyCondition(result, qualityGate, metric, "LT", "80");
+ }
+
+ @Test
+ public void create_condition_throws_NPE_if_errorThreshold_is_null() {
+ 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(NullPointerException.class);
+ expectedException.expectMessage("errorThreshold can not be null");
+
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null);
}
@Test
expectedException.expect(BadRequestException.class);
expectedException.expectMessage(format("Condition on metric '%s' already exists.", metric.getShortName()));
- underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "90", null);
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "90");
}
@Test
expectedException.expect(NotFoundException.class);
expectedException.expectMessage("There is no metric with key=new_coverage");
- underTest.createCondition(db.getSession(), qualityGate, "new_coverage", "LT", null, "80");
+ underTest.createCondition(db.getSession(), qualityGate, "new_coverage", "LT", "80");
}
@Test
expectedException.expect(BadRequestException.class);
expectedException.expectMessage(format("Metric '%s' cannot be used to define a condition.", metric.getKey()));
- underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, "80");
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", "80");
}
@Test
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Operator UNKNOWN is not allowed for metric type PERCENT.");
- underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "UNKNOWN", null, "80");
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "UNKNOWN", "90");
}
@Test
MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false));
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization());
- QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "3");
+ QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "3");
- verifyCondition(result, qualityGate, metric, "GT", null, "3");
- }
-
- @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(db.getSession(), qualityGate, metric.getKey(), "GT", "6", null);
+ verifyCondition(result, qualityGate, metric, "GT", "3");
}
@Test
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("'80' is not a valid rating");
- underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "80");
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "80");
}
@Test
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("There's no worse rating than E (5)");
- underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "5", 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);
-
- verifyCondition(result, qualityGate, metric, "EQ", value, null);
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "5");
}
@Test
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);
+ QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", value);
- verifyCondition(result, qualityGate, metric, "EQ", null, value);
+ verifyCondition(result, qualityGate, metric, "EQ", value);
}
@Test
@UseDataProvider("invalid_values")
- public void fail_to_create_warning_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) {
+ 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", value, null);
+ underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", value);
}
@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));
+ public void update_condition() {
+ 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").setErrorThreshold("80"));
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
+ QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "LT", "80");
- underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, value);
+ verifyCondition(result, qualityGate, metric, "LT", "80");
}
@Test
- public void update_condition() {
+ public void update_condition_throws_NPE_if_errorThreshold_is_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"));
+ c -> c.setOperator("LT").setErrorThreshold("80"));
- QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60", null);
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("errorThreshold can not be null");
- verifyCondition(result, qualityGate, metric, "GT", "60", null);
+ underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", null);
}
@Test
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));
+ c -> c.setOperator("LT").setErrorThreshold("80"));
- QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null);
+ QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4");
- verifyCondition(result, qualityGate, metric, "GT", "4", null);
+ verifyCondition(result, qualityGate, metric, "GT", "4");
}
@Test
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"));
+ c -> c.setOperator("LT").setErrorThreshold("3"));
expectedException.expect(BadRequestException.class);
expectedException.expectMessage(format("The metric '%s' cannot be used", metric.getShortName()));
- underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null);
+ underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4");
}
@Test
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"));
+ c -> c.setOperator("LT").setErrorThreshold("80"));
expectedException.expect(BadRequestException.class);
expectedException.expectMessage(format("Metric '%s' cannot be used to define a condition.", metric.getKey()));
- underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60", null);
- }
-
- @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"));
-
- QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value, null);
-
- verifyCondition(result, qualityGate, metric, "EQ", value, null);
+ underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60");
}
@Test
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"));
+ c -> c.setOperator("LT").setErrorThreshold("80"));
- QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", null, value);
-
- verifyCondition(result, qualityGate, metric, "EQ", null, value);
- }
-
- @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"));
-
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName()));
+ QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value);
- underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value, null);
+ verifyCondition(result, qualityGate, metric, "EQ", value);
}
@Test
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"));
+ c -> c.setOperator("LT").setErrorThreshold("80"));
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);
+ underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value);
}
@DataProvider
};
}
- private void verifyCondition(QualityGateConditionDto dto, QualityGateDto qualityGate, MetricDto metric, String operator, @Nullable String warning, @Nullable String error) {
+ private void verifyCondition(QualityGateConditionDto dto, QualityGateDto qualityGate, MetricDto metric, String operator, String error) {
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(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);
}
createBuiltInConditions(builtInQualityGate);
// Add another condition
qualityGateConditionsUpdater.createCondition(dbSession, builtInQualityGate,
- NEW_SECURITY_REMEDIATION_EFFORT_KEY, OPERATOR_GREATER_THAN, null, "5");
+ NEW_SECURITY_REMEDIATION_EFFORT_KEY, OPERATOR_GREATER_THAN, "5");
dbSession.commit();
underTest.start();
QualityGateConditionDto conditionDto = new QualityGateConditionDto()
.setMetricId(-1) // This Id does not exist
.setOperator(OPERATOR_GREATER_THAN)
- .setErrorThreshold("1")
- .setWarningThreshold("1");
+ .setErrorThreshold("1");
gateConditionDao.insert(conditionDto, dbSession);
dbSession.commit();
assertThat(qualityGateDto.getCreatedAt()).isNotNull();
assertThat(qualityGateDto.isBuiltIn()).isTrue();
assertThat(gateConditionDao.selectForQualityGate(dbSession, qualityGateDto.getId()))
- .extracting(QualityGateConditionDto::getMetricId, QualityGateConditionDto::getOperator, QualityGateConditionDto::getWarningThreshold,
+ .extracting(QualityGateConditionDto::getMetricId, QualityGateConditionDto::getOperator,
QualityGateConditionDto::getErrorThreshold)
.containsOnly(
- tuple(newReliability.getId().longValue(), OPERATOR_GREATER_THAN, null, "1"),
- tuple(newSecurity.getId().longValue(), OPERATOR_GREATER_THAN, null, "1"),
- tuple(newMaintainability.getId().longValue(), OPERATOR_GREATER_THAN, null, "1"),
- tuple(newCoverage.getId().longValue(), OPERATOR_LESS_THAN, null, "80"),
- tuple(newDuplication.getId().longValue(), OPERATOR_GREATER_THAN, null, "3"));
+ tuple(newReliability.getId().longValue(), OPERATOR_GREATER_THAN, "1"),
+ tuple(newSecurity.getId().longValue(), OPERATOR_GREATER_THAN, "1"),
+ tuple(newMaintainability.getId().longValue(), OPERATOR_GREATER_THAN, "1"),
+ tuple(newCoverage.getId().longValue(), OPERATOR_LESS_THAN, "80"),
+ tuple(newDuplication.getId().longValue(), OPERATOR_GREATER_THAN, "3"));
}
private List<QualityGateConditionDto> createBuiltInConditions(QualityGateDto qg) {
List<QualityGateConditionDto> conditions = new ArrayList<>();
conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg,
- NEW_SECURITY_RATING_KEY, OPERATOR_GREATER_THAN, null, "1"));
+ NEW_SECURITY_RATING_KEY, OPERATOR_GREATER_THAN, "1"));
conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg,
- NEW_RELIABILITY_RATING_KEY, OPERATOR_GREATER_THAN, null, "1"));
+ NEW_RELIABILITY_RATING_KEY, OPERATOR_GREATER_THAN, "1"));
conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg,
- NEW_MAINTAINABILITY_RATING_KEY, OPERATOR_GREATER_THAN, null, "1"));
+ NEW_MAINTAINABILITY_RATING_KEY, OPERATOR_GREATER_THAN, "1"));
conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg,
- NEW_COVERAGE_KEY, OPERATOR_LESS_THAN, null, "80"));
+ NEW_COVERAGE_KEY, OPERATOR_LESS_THAN, "80"));
conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg,
- NEW_DUPLICATED_LINES_DENSITY_KEY, OPERATOR_GREATER_THAN, null, "3"));
+ NEW_DUPLICATED_LINES_DENSITY_KEY, OPERATOR_GREATER_THAN, "3"));
return conditions;
}
assertThat(actual.getUuid()).isNotEqualTo(qualityGate.getUuid());
assertThat(db.getDbClient().gateConditionDao().selectForQualityGate(dbSession, qualityGate.getId()))
- .extracting(c-> (int) c.getMetricId(), QualityGateConditionDto::getWarningThreshold, QualityGateConditionDto::getErrorThreshold)
- .containsExactlyInAnyOrder(tuple(metric.getId(), condition.getWarningThreshold(), condition.getErrorThreshold()));
+ .extracting(c-> (int) c.getMetricId(), QualityGateConditionDto::getErrorThreshold)
+ .containsExactlyInAnyOrder(tuple(metric.getId(), condition.getErrorThreshold()));
}
@Test
package org.sonar.server.qualitygate.ws;
import java.util.ArrayList;
-import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_METRIC;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_OPERATOR;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ORGANIZATION;
-import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_WARNING;
public class CreateConditionActionTest {
private WsActionTester ws = new WsActionTester(underTest);
- @Test
- public void create_warning_condition() {
- 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_ORGANIZATION, organization.getKey())
- .execute();
-
- assertCondition(qualityGate, metric, "LT", "90", null, null);
- }
-
@Test
public void create_error_condition() {
OrganizationDto organization = db.organizations().insert();
.setParam(PARAM_ORGANIZATION, organization.getKey())
.execute();
- assertCondition(qualityGate, metric, "LT", null, "90", null);
+ assertCondition(qualityGate, metric, "LT", "90");
}
@Test
.setParam(PARAM_ORGANIZATION, organization.getKey())
.execute();
- assertCondition(qualityGate, metric, "LT", null, "90", 1);
+ assertCondition(qualityGate, metric, "LT", "90");
}
@Test
.setParam(PARAM_GATE_ID, qualityGate.getId().toString())
.setParam(PARAM_METRIC, metric.getKey())
.setParam(PARAM_OPERATOR, "LT")
- .setParam(PARAM_WARNING, "90")
- .execute();
-
- assertCondition(qualityGate, metric, "LT", "90", null, null);
- }
-
- @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())
+ .setParam(PARAM_ERROR, "10")
.execute();
- assertCondition(qualityGate, metric, "LT", null, "90", null);
+ assertCondition(qualityGate, metric, "LT", "10");
}
@Test
.setParam(PARAM_METRIC, metric.getKey())
.setParam(PARAM_OPERATOR, "LT")
.setParam(PARAM_ERROR, "45")
- .setParam(PARAM_WARNING, "90")
.setParam(PARAM_ORGANIZATION, organization.getKey())
.executeProtobuf(CreateConditionResponse.class);
assertThat(response.getId()).isEqualTo(condition.getId());
assertThat(response.getMetric()).isEqualTo(metric.getKey());
assertThat(response.getOp()).isEqualTo("LT");
- assertThat(response.getWarning()).isEqualTo("90");
assertThat(response.getError()).isEqualTo("45");
}
.containsExactlyInAnyOrder(
tuple("gateId", true),
tuple("metric", true),
+ tuple("error", true),
tuple("op", false),
- tuple("warning", false),
- tuple("error", false),
tuple("organization", false));
}
- private void assertCondition(QualityGateDto qualityGate, MetricDto metric, String operator, @Nullable String warning, @Nullable String error, @Nullable Integer period) {
+ private void assertCondition(QualityGateDto qualityGate, MetricDto metric, String operator, String error) {
assertThat(dbClient.gateConditionDao().selectForQualityGate(dbSession, qualityGate.getId()))
.extracting(QualityGateConditionDto::getQualityGateId, QualityGateConditionDto::getMetricId, QualityGateConditionDto::getOperator,
- QualityGateConditionDto::getWarningThreshold, QualityGateConditionDto::getErrorThreshold)
- .containsExactlyInAnyOrder(tuple(qualityGate.getId(), metric.getId().longValue(), operator, warning, error));
+ QualityGateConditionDto::getErrorThreshold)
+ .containsExactlyInAnyOrder(tuple(qualityGate.getId(), metric.getId().longValue(), operator, error));
}
private void logInAsQualityGateAdmin(OrganizationDto organization) {
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
@Test
public void test_definition() {
WebService.Action action = ws.getDef();
- assertThat(action.changelog()).extracting(Change::getVersion, Change::getDescription).containsExactly(
- tuple("6.4", "The field 'ignoredConditions' is added to the response"));
assertThat(action.params())
.extracting(WebService.Param::key, WebService.Param::isRequired)
.containsExactlyInAnyOrder(
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.System2;
assertThat(response.getIsBuiltIn()).isFalse();
assertThat(response.getConditionsList()).hasSize(2);
assertThat(response.getConditionsList())
- .extracting(Condition::getId, Condition::getMetric, Condition::getOp, Condition::getError, Condition::getWarning)
+ .extracting(Condition::getId, Condition::getMetric, Condition::getOp, Condition::getError)
.containsExactlyInAnyOrder(
- tuple(condition1.getId(), metric1.getKey(), "GT", condition1.getErrorThreshold(), condition1.getWarningThreshold()),
- tuple(condition2.getId(), metric2.getKey(), "LT", condition2.getErrorThreshold(), condition2.getWarningThreshold()));
+ tuple(condition1.getId(), metric1.getKey(), "GT", condition1.getErrorThreshold()),
+ tuple(condition2.getId(), metric2.getKey(), "LT", condition2.getErrorThreshold()));
}
@Test
QGateWithOrgDto qualityGate2 = db.qualityGates().insertQualityGate(organization, qg -> qg.setName("My Quality Gate 2"));
db.qualityGates().setDefaultQualityGate(organization, qualityGate2);
MetricDto blockerViolationsMetric = db.measures().insertMetric(m -> m.setKey("blocker_violations"));
- MetricDto criticalViolationsMetric = db.measures().insertMetric(m -> m.setKey("critical_violations"));
- db.qualityGates().addCondition(qualityGate, blockerViolationsMetric, c -> c.setOperator("GT").setErrorThreshold("0").setWarningThreshold(null));
- db.qualityGates().addCondition(qualityGate, criticalViolationsMetric, c -> c.setOperator("LT").setErrorThreshold(null).setWarningThreshold("0"));
+ MetricDto criticalViolationsMetric = db.measures().insertMetric(m -> m.setKey("tests"));
+ db.qualityGates().addCondition(qualityGate, blockerViolationsMetric, c -> c.setOperator("GT").setErrorThreshold("0"));
+ db.qualityGates().addCondition(qualityGate, criticalViolationsMetric, c -> c.setOperator("LT").setErrorThreshold("10"));
String response = ws.newRequest()
.setParam("name", qualityGate.getName())
public void verify_definition() {
WebService.Action action = ws.getDef();
assertThat(action.since()).isEqualTo("4.3");
- assertThat(action.changelog()).extracting(Change::getVersion, Change::getDescription)
- .containsExactlyInAnyOrder(
- tuple("7.0", "'isBuiltIn' field is added to the response"),
- tuple("7.0", "'actions' field is added in the response"));
assertThat(action.params())
.extracting(Param::key, Param::isRequired)
.containsExactlyInAnyOrder(
*/
package org.sonar.server.qualitygate.ws;
-import javax.annotation.Nullable;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_METRIC;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_OPERATOR;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ORGANIZATION;
-import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_WARNING;
public class UpdateConditionActionTest {
private WsActionTester ws = new WsActionTester(underTest);
- @Test
- public void update_warning_condition() {
- 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"));
-
- 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")
- .execute();
-
- assertCondition(qualityGate, metric, "LT", "90", null);
- }
-
@Test
public void update_error_condition() {
OrganizationDto organization = db.organizations().insert();
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
MetricDto metric = insertMetric();
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
- c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80"));
+ c -> c.setOperator("GT").setErrorThreshold("80"));
ws.newRequest()
.setParam(PARAM_ORGANIZATION, organization.getKey())
.setParam(PARAM_ERROR, "90")
.execute();
- assertCondition(qualityGate, metric, "LT", null, "90");
+ assertCondition(qualityGate, metric, "LT", "90");
}
@Test
.setParam(PARAM_ID, Long.toString(condition.getId()))
.setParam(PARAM_METRIC, metric.getKey())
.setParam(PARAM_OPERATOR, "LT")
- .setParam(PARAM_WARNING, "90")
+ .setParam(PARAM_ERROR, "10")
.execute();
- assertCondition(qualityGate, metric, "LT", "90", null);
- }
-
- @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"));
-
- 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);
- }
-
- @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"));
-
- 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");
+ assertCondition(qualityGate, metric, "LT", "10");
}
@Test
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
MetricDto metric = insertMetric();
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
- c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80"));
+ c -> c.setOperator("GT").setErrorThreshold("80"));
CreateConditionResponse response = 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, "45")
.executeProtobuf(CreateConditionResponse.class);
assertThat(response.getId()).isEqualTo(condition.getId());
assertThat(response.getMetric()).isEqualTo(metric.getKey());
assertThat(response.getOp()).isEqualTo("LT");
- assertThat(response.getWarning()).isEqualTo("90");
assertThat(response.getError()).isEqualTo("45");
}
.setParam(PARAM_ID, Long.toString(condition.getId()))
.setParam(PARAM_METRIC, metric.getKey())
.setParam(PARAM_OPERATOR, "LT")
- .setParam(PARAM_WARNING, "90")
+ .setParam(PARAM_ERROR, "10")
.execute();
}
.setParam(PARAM_ID, "123")
.setParam(PARAM_METRIC, metric.getKey())
.setParam(PARAM_OPERATOR, "LT")
- .setParam(PARAM_WARNING, "90")
+ .setParam(PARAM_ERROR, "90")
.execute();
}
.setParam(PARAM_ID, Long.toString(condition.getId()))
.setParam(PARAM_METRIC, metric.getKey())
.setParam(PARAM_OPERATOR, "LT")
- .setParam(PARAM_WARNING, "90")
+ .setParam(PARAM_ERROR, "90")
.execute();
}
.setParam(PARAM_ID, Long.toString(condition.getId()))
.setParam(PARAM_METRIC, metric.getKey())
.setParam(PARAM_OPERATOR, "LT")
- .setParam(PARAM_WARNING, "90")
+ .setParam(PARAM_ERROR, "90")
.execute();
}
.containsExactlyInAnyOrder(
tuple("id", true),
tuple("metric", true),
+ tuple("error", true),
tuple("op", false),
- tuple("warning", false),
- tuple("error", false),
tuple("organization", false));
-
}
- private void assertCondition(QualityGateDto qualityGate, MetricDto metric, String operator, @Nullable String warning, @Nullable String error) {
+ private void assertCondition(QualityGateDto qualityGate, MetricDto metric, String operator, String error) {
assertThat(dbClient.gateConditionDao().selectForQualityGate(dbSession, qualityGate.getId()))
.extracting(QualityGateConditionDto::getQualityGateId, QualityGateConditionDto::getMetricId, QualityGateConditionDto::getOperator,
- QualityGateConditionDto::getWarningThreshold, QualityGateConditionDto::getErrorThreshold)
- .containsExactlyInAnyOrder(tuple(qualityGate.getId(), metric.getId().longValue(), operator, warning, error));
+ QualityGateConditionDto::getErrorThreshold)
+ .containsExactlyInAnyOrder(tuple(qualityGate.getId(), metric.getId().longValue(), operator, error));
}
private MetricDto insertMetric() {
"metric": "new_blocker_violations",
"op": "GT",
"period": 1,
- "warning": "",
"error": "0",
"actual": "14",
"level": "ERROR"
"metric": "new_critical_violations",
"op": "GT",
"period": 1,
- "warning": "",
"error": "0",
"actual": "1",
"level": "ERROR"
"metric": "new_sqale_debt_ratio",
"op": "GT",
"period": 1,
- "warning": "",
"error": "5",
"actual": "0.6562109862671661",
"level": "OK"
"metric": "reopened_issues",
"op": "GT",
"period": 1,
- "warning": "0",
"actual": "0",
"level": "OK"
},
"metric": "open_issues",
"op": "GT",
"period": 1,
- "warning": "0",
- "error": "",
+ "error": "0",
"actual": "17",
- "level": "WARN"
+ "level": "ERROR"
},
{
"metric": "skipped_tests",
"op": "GT",
"period": 1,
- "warning": "0",
- "error": "",
+ "error": "0",
"actual": "0",
"level": "OK"
}
"warning": "",
"error": "5",
"actual": "0.5670339761248853",
- "level": "WARN"
+ "level": "ERROR"
}
]
}
public static final class ConditionBuilder {
private static final String METRIC_KEY_CAN_NOT_BE_NULL = "metricKey cannot be null";
private static final String OPERATOR_CAN_NOT_BE_NULL = "operator cannot be null";
+ private static final String ERROR_THRESHOLD_CAN_NOT_BE_NULL = "errorThreshold cannot be null";
private String metricKey;
private QualityGate.Operator operator;
private String errorThreshold;
- private String warningThreshold;
private ConditionBuilder() {
// prevents instantiation outside PostProjectAnalysisTaskTester
return this;
}
- public ConditionBuilder setErrorThreshold(@Nullable String errorThreshold) {
- this.errorThreshold = errorThreshold;
+ public ConditionBuilder setErrorThreshold(String errorThreshold) {
+ this.errorThreshold = requireNonNull(errorThreshold, ERROR_THRESHOLD_CAN_NOT_BE_NULL);
return this;
}
+ /**
+ * @deprecated in 7.6. This method has no longer any effect.
+ */
+ @Deprecated
public ConditionBuilder setWarningThreshold(@Nullable String warningThreshold) {
- this.warningThreshold = warningThreshold;
return this;
}
return errorThreshold;
}
+ @Deprecated
@Override
public String getWarningThreshold() {
- return warningThreshold;
+ return null;
}
/**
", metricKey='" + metricKey + '\'' +
", operator=" + operator +
", errorThreshold='" + errorThreshold + '\'' +
- ", warningThreshold='" + warningThreshold + '\'' +
'}';
}
};
return errorThreshold;
}
+ @Deprecated
@Override
public String getWarningThreshold() {
- return warningThreshold;
+ return null;
}
/**
", metricKey='" + metricKey + '\'' +
", operator=" + operator +
", errorThreshold='" + errorThreshold + '\'' +
- ", warningThreshold='" + warningThreshold + '\'' +
", value='" + value + '\'' +
'}';
}
private void checkCommonProperties() {
requireNonNull(metricKey, METRIC_KEY_CAN_NOT_BE_NULL);
requireNonNull(operator, OPERATOR_CAN_NOT_BE_NULL);
- checkState(errorThreshold != null || warningThreshold != null, "At least one of errorThreshold and warningThreshold must be non null");
+ requireNonNull(errorThreshold, ERROR_THRESHOLD_CAN_NOT_BE_NULL);
}
}
enum Status {
/** at least one threshold is defined, no threshold is reached */
OK,
- /** at least one warning threshold is reached, no error threshold is reached */
+ /**
+ * @deprecated in 7.6.
+ */
+ @Deprecated
WARN,
/** at least one error threshold is reached */
ERROR
String getMetricKey();
/**
- * The operator used to evaluate the error and/or warning thresholds against the value of the measure
+ * The operator used to evaluate the error threshold against the value of the measure
*/
Operator getOperator();
/**
- * <p>
- * At least one of {@link #getErrorThreshold()} and {@link #getWarningThreshold()} is guaranteed to be non {@code null}.
- *
- *
- * @see #getWarningThreshold()
+ * The threshold value which makes the quality gates status change to {@link EvaluationStatus#ERROR} when it's reached.
*/
- @CheckForNull
String getErrorThreshold();
/**
- *
- * <p>
- * At least one of {@link #getErrorThreshold()} and {@link #getWarningThreshold()} is guaranteed to be non {@code null}.
- *
- *
- * @see #getErrorThreshold()
+ * @deprecated in 7.6. Implementations should always return null.
*/
+ @Deprecated
@CheckForNull
String getWarningThreshold();
*/
NO_VALUE,
/**
- * Condition evaluated as OK, neither error nor warning thresholds have been reached.
+ * Condition evaluated as OK, error thresholds has not been reached.
*/
OK,
/**
* Condition evaluated as WARN, only warning thresholds has been reached.
+ * @deprecated in 7.6
*/
+ @Deprecated
WARN,
/**
* Condition evaluated as ERROR, error thresholds has been reached (and most likely warning thresholds too).
}
public enum Level {
- OK("Green"), WARN("Orange"), ERROR("Red");
+ OK("Green"),
+ /**
+ * @deprecated in 7.6.
+ */
+ @Deprecated
+ WARN("Orange"),
+ ERROR("Red");
private static final List<String> NAMES = Arrays.stream(values())
.map(Level::name)
private static final String SOME_METRIC_KEY = "some metric key";
private static final QualityGate.Operator SOME_OPERATOR = QualityGate.Operator.GREATER_THAN;
private static final String SOME_ERROR_THRESHOLD = "some error threshold";
- private static final String SOME_WARNING_THRESHOLD = "some warning threshold";
private static final QualityGate.EvaluationStatus SOME_STATUS_BUT_NO_VALUE = QualityGate.EvaluationStatus.OK;
private static final String SOME_VALUE = "some value";
@Test
public void buildNoValue_throws_NPE_if_metricKey_is_null() {
- underTest.setOperator(SOME_OPERATOR).setErrorThreshold(SOME_ERROR_THRESHOLD).setWarningThreshold(SOME_WARNING_THRESHOLD);
+ underTest.setOperator(SOME_OPERATOR).setErrorThreshold(SOME_ERROR_THRESHOLD);
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("metricKey cannot be null");
@Test
public void buildNoValue_throws_NPE_if_operator_is_null() {
- underTest.setMetricKey(SOME_METRIC_KEY).setErrorThreshold(SOME_ERROR_THRESHOLD).setWarningThreshold(SOME_WARNING_THRESHOLD);
+ underTest.setMetricKey(SOME_METRIC_KEY).setErrorThreshold(SOME_ERROR_THRESHOLD);
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("operator cannot be null");
}
@Test
- public void buildNoValue_throws_ISE_if_both_warningThreshold_and_errorThreshold_are_null() {
+ public void buildNoValue_throws_NPE_if_errorThreshold_is_null() {
underTest.setMetricKey(SOME_METRIC_KEY).setOperator(SOME_OPERATOR);
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("At least one of errorThreshold and warningThreshold must be non null");
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("errorThreshold cannot be null");
underTest.buildNoValue();
}
condition.getValue();
}
- @Test
- public void buildNoValue_does_not_fail_when_only_errorThreshold_is_set() {
- underTest.setMetricKey(SOME_METRIC_KEY).setOperator(SOME_OPERATOR).setErrorThreshold(SOME_ERROR_THRESHOLD);
-
- underTest.buildNoValue();
- }
-
- @Test
- public void buildNoValue_does_not_fail_when_only_wardThreshold_is_set() {
- underTest.setMetricKey(SOME_METRIC_KEY).setOperator(SOME_OPERATOR).setWarningThreshold(SOME_WARNING_THRESHOLD);
-
- underTest.buildNoValue();
- }
-
@Test
public void buildNoValue_returns_new_instance_at_each_call() {
initValidBuilder();
assertThat(underTest.buildNoValue().toString())
.isEqualTo(
"Condition{status=NO_VALUE, metricKey='some metric key', operator=GREATER_THAN, " +
- "errorThreshold='some error threshold', warningThreshold='some warning threshold'}");
+ "errorThreshold='some error threshold'}");
}
@Test
assertThat(condition.getMetricKey()).isEqualTo(SOME_METRIC_KEY);
assertThat(condition.getOperator()).isEqualTo(SOME_OPERATOR);
assertThat(condition.getErrorThreshold()).isEqualTo(SOME_ERROR_THRESHOLD);
- assertThat(condition.getWarningThreshold()).isEqualTo(SOME_WARNING_THRESHOLD);
}
@Test
@Test
public void build_throws_NPE_if_metricKey_is_null() {
- underTest.setOperator(SOME_OPERATOR).setErrorThreshold(SOME_ERROR_THRESHOLD).setWarningThreshold(SOME_WARNING_THRESHOLD);
+ underTest.setOperator(SOME_OPERATOR).setErrorThreshold(SOME_ERROR_THRESHOLD);
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("metricKey cannot be null");
@Test
public void build_throws_NPE_if_operator_is_null() {
- underTest.setMetricKey(SOME_METRIC_KEY).setErrorThreshold(SOME_ERROR_THRESHOLD).setWarningThreshold(SOME_WARNING_THRESHOLD);
+ underTest.setMetricKey(SOME_METRIC_KEY).setErrorThreshold(SOME_ERROR_THRESHOLD);
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("operator cannot be null");
}
@Test
- public void build_does_not_fail_when_only_errorThreshold_is_set() {
- underTest.setMetricKey(SOME_METRIC_KEY).setOperator(SOME_OPERATOR).setErrorThreshold(SOME_ERROR_THRESHOLD);
-
- underTest.build(SOME_STATUS_BUT_NO_VALUE, SOME_VALUE);
- }
-
- @Test
- public void build_does_not_fail_when_only_wardThreshold_is_set() {
- underTest.setMetricKey(SOME_METRIC_KEY).setOperator(SOME_OPERATOR).setWarningThreshold(SOME_WARNING_THRESHOLD);
-
- underTest.build(SOME_STATUS_BUT_NO_VALUE, SOME_VALUE);
- }
-
- @Test
- public void build_throws_ISE_if_both_warningThreshold_and_errorThreshold_are_null() {
+ public void build_throws_NPE_if_errorThreshold_is_null() {
underTest.setMetricKey(SOME_METRIC_KEY).setOperator(SOME_OPERATOR);
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("At least one of errorThreshold and warningThreshold must be non null");
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("errorThreshold cannot be null");
underTest.build(SOME_STATUS_BUT_NO_VALUE, SOME_VALUE);
}
assertThat(underTest.build(SOME_STATUS_BUT_NO_VALUE, SOME_VALUE).toString())
.isEqualTo(
"Condition{status=OK, metricKey='some metric key', operator=GREATER_THAN, "
- + "errorThreshold='some error threshold', warningThreshold='some warning threshold', value='some value'}");
+ + "errorThreshold='some error threshold', value='some value'}");
}
@Test
assertThat(condition.getMetricKey()).isEqualTo(SOME_METRIC_KEY);
assertThat(condition.getOperator()).isEqualTo(SOME_OPERATOR);
assertThat(condition.getErrorThreshold()).isEqualTo(SOME_ERROR_THRESHOLD);
- assertThat(condition.getWarningThreshold()).isEqualTo(SOME_WARNING_THRESHOLD);
assertThat(condition.getValue()).isEqualTo(SOME_VALUE);
}
private PostProjectAnalysisTaskTester.ConditionBuilder initValidBuilder() {
- underTest.setMetricKey(SOME_METRIC_KEY).setOperator(SOME_OPERATOR).setErrorThreshold(SOME_ERROR_THRESHOLD).setWarningThreshold(SOME_WARNING_THRESHOLD);
+ underTest.setMetricKey(SOME_METRIC_KEY).setOperator(SOME_OPERATOR).setErrorThreshold(SOME_ERROR_THRESHOLD);
return underTest;
}
}
*/
package org.sonarqube.ws.client.qualitygates;
-import java.util.List;
import javax.annotation.Generated;
/**
private String metric;
private String op;
private String organization;
- private String warning;
/**
* Example value: "10"
public String getOrganization() {
return organization;
}
-
- /**
- * Example value: "5"
- */
- public CreateConditionRequest setWarning(String warning) {
- this.warning = warning;
- return this;
- }
-
- public String getWarning() {
- return warning;
- }
}
.setParam("gateId", request.getGateId())
.setParam("metric", request.getMetric())
.setParam("op", request.getOp())
- .setParam("organization", request.getOrganization())
- .setParam("warning", request.getWarning()),
+ .setParam("organization", request.getOrganization()),
CreateConditionResponse.parser());
}
.setParam("id", request.getId())
.setParam("metric", request.getMetric())
.setParam("op", request.getOp())
- .setParam("organization", request.getOrganization())
- .setParam("warning", request.getWarning()),
+ .setParam("organization", request.getOrganization()),
UpdateConditionResponse.parser());
}
}
private String metric;
private String op;
private String organization;
- private String warning;
/**
* Example value: "10"
public String getOrganization() {
return organization;
}
-
- /**
- * Example value: "5"
- */
- public UpdateConditionRequest setWarning(String warning) {
- this.warning = warning;
- return this;
- }
-
- public String getWarning() {
- return warning;
- }
}
optional int64 id = 1;
optional string metric = 2;
optional string op = 3;
- optional string warning = 4;
optional string error = 5;
}
optional int64 id = 1;
optional string metric = 2;
optional string op = 3;
- optional string warning = 4;
optional string error = 5;
}
optional int64 id = 1;
optional string metric = 2;
optional string op = 4;
- optional string warning = 5;
optional string error = 6;
}
}