@@ -53,7 +53,7 @@ class ConditionImpl implements QualityGate.Condition { | |||
this.operator = builder.operator; | |||
this.errorThreshold = builder.errorThreshold; | |||
this.warningThreshold = builder.warningThreshold; | |||
this.onLeakPeriod = builder.onLeakPeriod; | |||
this.onLeakPeriod = builder.metricKey.startsWith("new_"); | |||
this.value = builder.value; | |||
} | |||
@@ -82,7 +82,6 @@ class ConditionImpl implements QualityGate.Condition { | |||
private String errorThreshold; | |||
@CheckForNull | |||
private String warningThreshold; | |||
private boolean onLeakPeriod; | |||
@CheckForNull | |||
private String value; | |||
private QualityGate.EvaluationStatus status; | |||
@@ -111,8 +110,11 @@ class ConditionImpl implements QualityGate.Condition { | |||
return this; | |||
} | |||
/** | |||
* @deprecated in 7.6. This method has no longer any effect. | |||
*/ | |||
@Deprecated | |||
public Builder setOnLeakPeriod(boolean onLeakPeriod) { | |||
this.onLeakPeriod = onLeakPeriod; | |||
return this; | |||
} | |||
@@ -156,6 +158,10 @@ class ConditionImpl implements QualityGate.Condition { | |||
return warningThreshold; | |||
} | |||
/** | |||
* @deprecated in 7.6. Conditions "on leak period" were removed. Use "New X" conditions instead. | |||
*/ | |||
@Deprecated | |||
@Override | |||
public boolean isOnLeakPeriod() { | |||
return onLeakPeriod; | |||
@@ -176,7 +182,6 @@ class ConditionImpl implements QualityGate.Condition { | |||
", operator=" + operator + | |||
", errorThreshold='" + errorThreshold + '\'' + | |||
", warningThreshold='" + warningThreshold + '\'' + | |||
", onLeakPeriod=" + onLeakPeriod + | |||
", value='" + value + '\'' + | |||
'}'; | |||
} |
@@ -25,8 +25,6 @@ import javax.annotation.Nonnull; | |||
import org.sonar.api.ce.posttask.QualityGate; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.Condition; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.ConditionStatus; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.Condition; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.ConditionStatus; | |||
import static com.google.common.base.Preconditions.checkState; | |||
import static java.lang.String.format; | |||
@@ -55,7 +53,6 @@ class ConditionToCondition implements Function<Condition, QualityGate.Condition> | |||
.setOperator(convert(input.getOperator())) | |||
.setErrorThreshold(input.getErrorThreshold()) | |||
.setWarningThreshold(input.getWarningThreshold()) | |||
.setOnLeakPeriod(input.hasPeriod()) | |||
.setValue(conditionStatus.getValue()) | |||
.build(); | |||
} |
@@ -25,8 +25,6 @@ import java.util.List; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.sonar.ce.task.projectanalysis.measure.Measure; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.Condition; | |||
import org.sonar.ce.task.projectanalysis.measure.Measure; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.Condition; | |||
import static com.google.common.collect.FluentIterable.from; | |||
import static java.util.Objects.requireNonNull; | |||
@@ -64,7 +62,9 @@ public class QualityGateDetailsData { | |||
JsonObject result = new JsonObject(); | |||
result.addProperty("metric", condition.getMetric().getKey()); | |||
result.addProperty("op", condition.getOperator().getDbValue()); | |||
if (condition.hasPeriod()) { | |||
if (condition.useVariation()) { | |||
// without this for new_ metrics, the UI will show "-" instead of | |||
// the actual value in the QG failure reason | |||
result.addProperty("period", 1); | |||
} | |||
if (condition.getWarningThreshold() != null) { |
@@ -24,7 +24,6 @@ import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.sonar.ce.task.projectanalysis.metric.Metric; | |||
import org.sonar.ce.task.projectanalysis.metric.Metric; | |||
import static java.util.Objects.hash; | |||
import static java.util.Objects.requireNonNull; | |||
@@ -52,14 +51,13 @@ public class Condition { | |||
private final String warningThreshold; | |||
@CheckForNull | |||
private final String errorThreshold; | |||
private final boolean hasPeriod; | |||
private final boolean useVariation; | |||
public Condition(Metric metric, String operator, | |||
@Nullable String errorThreshold, @Nullable String warningThreshold, | |||
boolean hasPeriod) { | |||
@Nullable String errorThreshold, @Nullable String warningThreshold) { | |||
this.metric = requireNonNull(metric); | |||
this.operator = parseFromDbValue(requireNonNull(operator)); | |||
this.hasPeriod = hasPeriod; | |||
this.useVariation = metric.getKey().startsWith("new_"); | |||
this.errorThreshold = errorThreshold; | |||
this.warningThreshold = warningThreshold; | |||
} | |||
@@ -77,8 +75,8 @@ public class Condition { | |||
return metric; | |||
} | |||
public boolean hasPeriod() { | |||
return hasPeriod; | |||
public boolean useVariation() { | |||
return useVariation; | |||
} | |||
public Operator getOperator() { | |||
@@ -104,20 +102,18 @@ public class Condition { | |||
return false; | |||
} | |||
Condition that = (Condition) o; | |||
return java.util.Objects.equals(metric, that.metric) | |||
&& java.util.Objects.equals(hasPeriod, that.hasPeriod); | |||
return java.util.Objects.equals(metric, that.metric); | |||
} | |||
@Override | |||
public int hashCode() { | |||
return hash(metric, hasPeriod); | |||
return hash(metric); | |||
} | |||
@Override | |||
public String toString() { | |||
return MoreObjects.toStringHelper(this) | |||
.add("metric", metric) | |||
.add("hasPeriod", hasPeriod) | |||
.add("operator", operator) | |||
.add("warningThreshold", warningThreshold) | |||
.add("errorThreshold", errorThreshold) |
@@ -24,7 +24,6 @@ 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; | |||
@@ -116,7 +115,7 @@ public final class ConditionEvaluator { | |||
@CheckForNull | |||
private static Comparable parseMeasure(Condition condition, Measure measure) { | |||
if (condition.hasPeriod()) { | |||
if (condition.useVariation()) { | |||
return parseMeasureFromVariation(condition, measure); | |||
} | |||
switch (measure.getValueType()) { | |||
@@ -142,29 +141,26 @@ public final class ConditionEvaluator { | |||
@CheckForNull | |||
private static Comparable parseMeasureFromVariation(Condition condition, Measure measure) { | |||
Optional<Double> periodValue = getPeriodValue(measure); | |||
if (periodValue.isPresent()) { | |||
switch (condition.getMetric().getType().getValueType()) { | |||
case BOOLEAN: | |||
return periodValue.get().intValue() == 1; | |||
case INT: | |||
return periodValue.get().intValue(); | |||
case LONG: | |||
return periodValue.get().longValue(); | |||
case DOUBLE: | |||
return periodValue.get(); | |||
case NO_VALUE: | |||
case STRING: | |||
case LEVEL: | |||
default: | |||
throw new IllegalArgumentException("Period conditions are not supported for metric type " + condition.getMetric().getType()); | |||
} | |||
if (!measure.hasVariation()) { | |||
return null; | |||
} | |||
return null; | |||
} | |||
private static Optional<Double> getPeriodValue(Measure measure) { | |||
return measure.hasVariation() ? Optional.of(measure.getVariation()) : Optional.empty(); | |||
Double variation = measure.getVariation(); | |||
Metric.MetricType metricType = condition.getMetric().getType(); | |||
switch (metricType.getValueType()) { | |||
case BOOLEAN: | |||
return variation.intValue() == 1; | |||
case INT: | |||
return variation.intValue(); | |||
case LONG: | |||
return variation.longValue(); | |||
case DOUBLE: | |||
return variation; | |||
case NO_VALUE: | |||
case STRING: | |||
case LEVEL: | |||
default: | |||
throw new IllegalArgumentException("Unsupported metric type " + metricType); | |||
} | |||
} | |||
} |
@@ -24,23 +24,15 @@ import java.util.Locale; | |||
import java.util.Map; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.api.i18n.I18n; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.api.utils.Duration; | |||
import org.sonar.api.utils.Durations; | |||
import org.sonar.ce.task.projectanalysis.metric.Metric; | |||
import org.sonar.ce.task.projectanalysis.period.Period; | |||
import org.sonar.core.timemachine.Periods; | |||
import org.sonar.ce.task.projectanalysis.measure.Measure; | |||
import org.sonar.ce.task.projectanalysis.metric.Metric; | |||
import org.sonar.ce.task.projectanalysis.period.Period; | |||
import org.sonar.ce.task.projectanalysis.period.PeriodHolder; | |||
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 String VARIATION_METRIC_PREFIX = "new_"; | |||
private static final String VARIATION = "variation"; | |||
private static final Map<Condition.Operator, String> OPERATOR_LABELS = ImmutableMap.of( | |||
Condition.Operator.EQUALS, "=", | |||
Condition.Operator.NOT_EQUALS, "!=", | |||
@@ -49,14 +41,10 @@ public final class EvaluationResultTextConverterImpl implements EvaluationResult | |||
private final I18n i18n; | |||
private final Durations durations; | |||
private final Periods periods; | |||
private final PeriodHolder periodHolder; | |||
public EvaluationResultTextConverterImpl(I18n i18n, Durations durations, Periods periods, PeriodHolder periodHolder) { | |||
public EvaluationResultTextConverterImpl(I18n i18n, Durations durations) { | |||
this.i18n = i18n; | |||
this.durations = durations; | |||
this.periods = periods; | |||
this.periodHolder = periodHolder; | |||
} | |||
@Override | |||
@@ -70,26 +58,15 @@ public final class EvaluationResultTextConverterImpl implements EvaluationResult | |||
} | |||
private String getAlertLabel(Condition condition, Measure.Level level) { | |||
boolean hasPeriod = condition.hasPeriod(); | |||
String metric = i18n.message(Locale.ENGLISH, "metric." + condition.getMetric().getKey() + ".name", condition.getMetric().getName()); | |||
StringBuilder stringBuilder = new StringBuilder(); | |||
stringBuilder.append(metric); | |||
if (hasPeriod && !condition.getMetric().getKey().startsWith(VARIATION_METRIC_PREFIX)) { | |||
String variation = i18n.message(Locale.ENGLISH, VARIATION, VARIATION).toLowerCase(Locale.ENGLISH); | |||
stringBuilder.append(" ").append(variation); | |||
} | |||
stringBuilder | |||
.append(" ").append(OPERATOR_LABELS.get(condition.getOperator())).append(" ") | |||
.append(alertValue(condition, level)); | |||
if (hasPeriod) { | |||
Period period = periodHolder.getPeriod(); | |||
stringBuilder.append(" ").append(periods.label(period.getMode(), period.getModeParameter(), DateUtils.longToDate(period.getSnapshotDate()))); | |||
} | |||
return stringBuilder.toString(); | |||
} | |||
@@ -28,7 +28,6 @@ import org.sonar.db.DbSession; | |||
import org.sonar.db.qualitygate.QualityGateConditionDto; | |||
import org.sonar.db.qualitygate.QualityGateDto; | |||
import org.sonar.ce.task.projectanalysis.analysis.Organization; | |||
import org.sonar.ce.task.projectanalysis.metric.MetricRepository; | |||
import org.sonar.server.qualitygate.ShortLivingBranchQualityGate; | |||
import static org.sonar.core.util.stream.MoreCollectors.toList; | |||
@@ -73,7 +72,7 @@ public class QualityGateServiceImpl implements QualityGateService { | |||
Iterable<Condition> conditions = dtos.stream() | |||
.map(input -> metricRepository.getOptionalById(input.getMetricId()) | |||
.map(metric -> new Condition(metric, input.getOperator(), input.getErrorThreshold(), input.getWarningThreshold(), input.getPeriod() != null)) | |||
.map(metric -> new Condition(metric, input.getOperator(), input.getErrorThreshold(), input.getWarningThreshold())) | |||
.orElse(null)) | |||
.filter(Objects::nonNull) | |||
.collect(toList(dtos.size())); | |||
@@ -86,7 +85,7 @@ public class QualityGateServiceImpl implements QualityGateService { | |||
ShortLivingBranchQualityGate.ID, | |||
ShortLivingBranchQualityGate.NAME, | |||
ShortLivingBranchQualityGate.CONDITIONS.stream() | |||
.map(c -> new Condition(metricRepository.getByKey(c.getMetricKey()), c.getOperator(), c.getErrorThreshold(), c.getWarnThreshold(), c.isOnLeak())) | |||
.map(c -> new Condition(metricRepository.getByKey(c.getMetricKey()), c.getOperator(), c.getErrorThreshold(), c.getWarnThreshold())) | |||
.collect(toList(ShortLivingBranchQualityGate.CONDITIONS.size()))); | |||
} | |||
@@ -22,7 +22,6 @@ package org.sonar.ce.task.projectanalysis.step; | |||
import com.google.common.base.Function; | |||
import com.google.common.collect.ImmutableMap; | |||
import com.google.common.collect.Multimap; | |||
import com.google.common.collect.Ordering; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.List; | |||
@@ -74,9 +73,6 @@ import static org.sonar.ce.task.projectanalysis.qualitygate.ConditionStatus.crea | |||
* It must be executed after the computation of differential measures {@link ComputeMeasureVariationsStep} | |||
*/ | |||
public class QualityGateMeasuresStep implements ComputationStep { | |||
// Condition on period should come first | |||
private static final Ordering<Condition> PERIOD_ORDERING = Ordering.natural().reverse().onResultOf(Condition::hasPeriod); | |||
private final TreeRootHolder treeRootHolder; | |||
private final QualityGateHolder qualityGateHolder; | |||
private final MutableQualityGateStatusHolder qualityGateStatusHolder; | |||
@@ -206,7 +202,7 @@ public class QualityGateMeasuresStep implements ComputationStep { | |||
private static MetricEvaluationResult evaluateQualityGate(Measure measure, Collection<Condition> conditions) { | |||
ConditionEvaluator conditionEvaluator = new ConditionEvaluator(); | |||
MetricEvaluationResult metricEvaluationResult = null; | |||
for (Condition newCondition : PERIOD_ORDERING.immutableSortedCopy(conditions)) { | |||
for (Condition newCondition : conditions) { | |||
EvaluationResult newEvaluationResult = conditionEvaluator.evaluate(newCondition, measure); | |||
if (metricEvaluationResult == null || newEvaluationResult.getLevel().ordinal() > metricEvaluationResult.evaluationResult.getLevel().ordinal()) { | |||
metricEvaluationResult = new MetricEvaluationResult(newEvaluationResult, newCondition); |
@@ -65,7 +65,7 @@ public class WebhookPostTask implements PostProjectAnalysisTask { | |||
Set<Condition> conditions = qg.getConditions().stream() | |||
.map(q -> { | |||
Condition condition = new Condition(q.getMetricKey(), Condition.Operator.valueOf(q.getOperator().name()), | |||
q.getErrorThreshold(), q.getWarningThreshold(), q.isOnLeakPeriod()); | |||
q.getErrorThreshold(), q.getWarningThreshold()); | |||
builder.addCondition(condition, | |||
EvaluatedCondition.EvaluationStatus.valueOf(q.getStatus().name()), | |||
q.getStatus() == org.sonar.api.ce.posttask.QualityGate.EvaluationStatus.NO_VALUE ? null : q.getValue()); |
@@ -46,7 +46,6 @@ public class ConditionImplTest { | |||
.setOperator(QualityGate.Operator.GREATER_THAN) | |||
.setErrorThreshold(ERROR_THRESHOLD) | |||
.setWarningThreshold(WARN_THRESHOLD) | |||
.setOnLeakPeriod(true) | |||
.setValue(VALUE); | |||
@Test | |||
@@ -140,7 +139,7 @@ public class ConditionImplTest { | |||
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', onLeakPeriod=true, value='value'}"); | |||
"ConditionImpl{status=OK, metricKey='metricKey', operator=GREATER_THAN, errorThreshold='error threshold', warningThreshold='warn threshold', value='value'}"); | |||
} | |||
@Test | |||
@@ -150,7 +149,7 @@ public class ConditionImplTest { | |||
assertThat(builder.build().toString()) | |||
.isEqualTo( | |||
"ConditionImpl{status=NO_VALUE, metricKey='metricKey', operator=GREATER_THAN, errorThreshold='error threshold', warningThreshold='warn threshold', onLeakPeriod=true, value='null'}"); | |||
"ConditionImpl{status=NO_VALUE, metricKey='metricKey', operator=GREATER_THAN, errorThreshold='error threshold', warningThreshold='warn threshold', value='null'}"); | |||
} | |||
@Test | |||
@@ -162,7 +161,6 @@ public class ConditionImplTest { | |||
assertThat(underTest.getOperator()).isEqualTo(QualityGate.Operator.GREATER_THAN); | |||
assertThat(underTest.getErrorThreshold()).isEqualTo(ERROR_THRESHOLD); | |||
assertThat(underTest.getWarningThreshold()).isEqualTo(WARN_THRESHOLD); | |||
assertThat(underTest.isOnLeakPeriod()).isEqualTo(true); | |||
assertThat(underTest.getValue()).isEqualTo(VALUE); | |||
} | |||
} |
@@ -46,7 +46,7 @@ public class ConditionToConditionTest { | |||
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, true); | |||
private static final Condition SOME_CONDITION = new Condition(newMetric(METRIC_KEY), Condition.Operator.EQUALS.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@@ -98,26 +98,15 @@ public class ConditionToConditionTest { | |||
@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, true); | |||
Condition condition = new Condition(newMetric(METRIC_KEY), operator.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD); | |||
ConditionToCondition underTest = new ConditionToCondition(of(condition, SOME_CONDITION_STATUS)); | |||
assertThat(underTest.apply(condition).getOperator().name()).isEqualTo(operator.name()); | |||
} | |||
@Test | |||
public void apply_sets_onLeakPeriod_flag_when_Condition_has_non_null_Period() { | |||
Condition noPeriodCondition = new Condition(newMetric(METRIC_KEY), Condition.Operator.NOT_EQUALS.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD, false); | |||
ConditionToCondition underTest = new ConditionToCondition(of( | |||
SOME_CONDITION, SOME_CONDITION_STATUS, | |||
noPeriodCondition, SOME_CONDITION_STATUS)); | |||
assertThat(underTest.apply(SOME_CONDITION).isOnLeakPeriod()).isTrue(); | |||
assertThat(underTest.apply(noPeriodCondition).isOnLeakPeriod()).isFalse(); | |||
} | |||
@Test | |||
public void apply_copies_value() { | |||
Condition otherCondition = new Condition(newMetric(METRIC_KEY), Condition.Operator.NOT_EQUALS.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD, false); | |||
Condition otherCondition = new Condition(newMetric(METRIC_KEY), Condition.Operator.NOT_EQUALS.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD); | |||
ConditionToCondition underTest = new ConditionToCondition(of( | |||
SOME_CONDITION, SOME_CONDITION_STATUS, | |||
otherCondition, ConditionStatus.NO_VALUE_STATUS)); |
@@ -391,7 +391,7 @@ public class PostProjectAnalysisTasksExecutorTest { | |||
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", false); | |||
return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), "error threshold", "warn threshold"); | |||
} | |||
} |
@@ -26,10 +26,15 @@ import org.sonar.ce.task.projectanalysis.qualitygate.Condition; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public class EvaluatedConditionTest { | |||
private static final Condition SOME_CONDITION = new Condition(mock(Metric.class), Condition.Operator.EQUALS.getDbValue(), "1", null, false); | |||
private static final Metric SOME_METRIC = mock(Metric.class); | |||
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 Measure.Level SOME_LEVEL = Measure.Level.OK; | |||
private static final String SOME_VALUE = "some value"; | |||
@@ -52,7 +52,7 @@ public class QualityGateDetailsDataTest { | |||
@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", true); | |||
Condition condition = new Condition(new MetricImpl(1, "key1", "name1", Metric.MetricType.STRING), Condition.Operator.GREATER_THAN.getDbValue(), "errorTh", "warnTh"); | |||
ImmutableList<EvaluatedCondition> evaluatedConditions = ImmutableList.of( | |||
new EvaluatedCondition(condition, Measure.Level.OK, value), | |||
new EvaluatedCondition(condition, Measure.Level.WARN, value), | |||
@@ -65,7 +65,6 @@ public class QualityGateDetailsDataTest { | |||
" {" + | |||
" \"metric\":\"key1\"," + | |||
" \"op\":\"GT\"," + | |||
" \"period\":1," + | |||
" \"warning\":\"warnTh\"," + | |||
" \"error\":\"errorTh\"," + | |||
" \"actual\":\"actualValue\"," + | |||
@@ -74,7 +73,6 @@ public class QualityGateDetailsDataTest { | |||
" {" + | |||
" \"metric\":\"key1\"," + | |||
" \"op\":\"GT\"," + | |||
" \"period\":1," + | |||
" \"warning\":\"warnTh\"," + | |||
" \"error\":\"errorTh\"," + | |||
" \"actual\":\"actualValue\"," + | |||
@@ -83,7 +81,6 @@ public class QualityGateDetailsDataTest { | |||
" {" + | |||
" \"metric\":\"key1\"," + | |||
" \"op\":\"GT\"," + | |||
" \"period\":1," + | |||
" \"warning\":\"warnTh\"," + | |||
" \"error\":\"errorTh\"," + | |||
" \"actual\":\"actualValue\"," + |
@@ -19,11 +19,14 @@ | |||
*/ | |||
package org.sonar.ce.task.projectanalysis.qualitygate; | |||
import com.google.common.collect.ImmutableList; | |||
import com.google.common.collect.ImmutableSet; | |||
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 org.junit.runner.RunWith; | |||
import org.sonar.ce.task.projectanalysis.measure.Measure; | |||
import org.sonar.ce.task.projectanalysis.metric.Metric; | |||
import org.sonar.ce.task.projectanalysis.metric.MetricImpl; | |||
@@ -53,6 +56,7 @@ import static org.sonar.ce.task.projectanalysis.qualitygate.Condition.Operator.L | |||
import static org.sonar.ce.task.projectanalysis.qualitygate.Condition.Operator.NOT_EQUALS; | |||
import static org.sonar.ce.task.projectanalysis.qualitygate.EvaluationResultAssert.assertThat; | |||
@RunWith(DataProviderRunner.class) | |||
public class ConditionEvaluatorTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@@ -241,8 +245,8 @@ public class ConditionEvaluatorTest { | |||
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", false), measure)).hasLevel(Measure.Level.WARN); | |||
assertThat(underTest.evaluate(new Condition(metric, LESS_THAN.getDbValue(), "10.3", "10.2", false), measure)).hasLevel(Measure.Level.ERROR); | |||
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); | |||
} | |||
@Test | |||
@@ -267,54 +271,71 @@ public class ConditionEvaluatorTest { | |||
} | |||
@Test | |||
public void test_condition_on_period() { | |||
for (MetricType metricType : ImmutableList.of(FLOAT, INT, WORK_DUR)) { | |||
Metric metric = createMetric(metricType); | |||
Measure measure = newMeasureBuilder().setVariation(3d).createNoValue(); | |||
@UseDataProvider("numericNewMetricTypes") | |||
public void test_condition_on_numeric_new_metric(MetricType metricType) { | |||
Metric metric = createNewMetric(metricType); | |||
Measure measure = newMeasureBuilder().setVariation(3d).createNoValue(); | |||
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null, true), measure)).hasLevel(OK); | |||
} | |||
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); | |||
} | |||
@Test | |||
public void condition_on_period_without_value_is_OK() { | |||
Metric metric = createMetric(FLOAT); | |||
@UseDataProvider("numericNewMetricTypes") | |||
public void condition_on_new_metric_without_value_is_OK(MetricType metricType) { | |||
Metric metric = createNewMetric(metricType); | |||
Measure measure = newMeasureBuilder().createNoValue(); | |||
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null, true), measure)).hasLevel(OK).hasValue(null); | |||
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null), measure)).hasLevel(OK).hasValue(null); | |||
} | |||
@Test | |||
public void test_condition_on_rating() { | |||
Metric metric = createMetric(RATING); | |||
Measure measure = newMeasureBuilder().create(4, "D"); | |||
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "4", null, false), measure)).hasLevel(OK).hasValue(4); | |||
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "2", null, false), measure)).hasLevel(ERROR).hasValue(4); | |||
@DataProvider | |||
public static Object[][] numericNewMetricTypes() { | |||
return new Object[][] { | |||
{FLOAT}, | |||
{INT}, | |||
{WORK_DUR}, | |||
}; | |||
} | |||
@Test | |||
public void test_condition_on_rating_on_leak_period() { | |||
Metric metric = createMetric(RATING); | |||
Measure measure = newMeasureBuilder().setVariation(4d).createNoValue(); | |||
@UseDataProvider("unsupportedNewMetricTypes") | |||
public void condition_on_new_metric_with_unsupported_type(MetricType metricType) { | |||
Metric metric = createNewMetric(metricType); | |||
Measure measure = newMeasureBuilder().setVariation(0d).createNoValue(); | |||
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "5", null, true), measure)).hasLevel(OK).hasValue(4); | |||
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "2", null, true), measure)).hasLevel(ERROR).hasValue(4); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Unsupported metric type " + metricType); | |||
underTest.evaluate(new Condition(metric, EQUALS.getDbValue(), "3", null), measure); | |||
} | |||
@DataProvider | |||
public static Object[][] unsupportedNewMetricTypes() { | |||
return new Object[][] { | |||
{STRING}, | |||
{LEVEL}, | |||
}; | |||
} | |||
@Test | |||
public void test_condition_on_rating_on_leak_period_when_variation_is_zero() { | |||
public void test_condition_on_rating() { | |||
Metric metric = createMetric(RATING); | |||
Measure measure = newMeasureBuilder().setVariation(0d).createNoValue(); | |||
Measure measure = newMeasureBuilder().create(4, "D"); | |||
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "4", null, true), measure)).hasLevel(OK).hasValue(0); | |||
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); | |||
} | |||
private static Condition createErrorCondition(Metric metric, Condition.Operator operator, String errorThreshold) { | |||
return new Condition(metric, operator.getDbValue(), errorThreshold, null, false); | |||
return new Condition(metric, operator.getDbValue(), errorThreshold, null); | |||
} | |||
private static MetricImpl createMetric(MetricType metricType) { | |||
return new MetricImpl(1, "key", "name", metricType); | |||
} | |||
private static MetricImpl createNewMetric(MetricType metricType) { | |||
return new MetricImpl(1, "new_key", "name", metricType); | |||
} | |||
} |
@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonar.ce.task.projectanalysis.qualitygate; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
@@ -36,14 +37,19 @@ public class ConditionTest { | |||
private static final Metric SOME_METRIC = mock(Metric.class); | |||
private static final String SOME_OPERATOR = "EQ"; | |||
@Before | |||
public void setUp() { | |||
when(SOME_METRIC.getKey()).thenReturn("dummy key"); | |||
} | |||
@Test(expected = NullPointerException.class) | |||
public void constructor_throws_NPE_for_null_metric_argument() { | |||
new Condition(null, SOME_OPERATOR, null, null, false); | |||
new Condition(null, SOME_OPERATOR, null, null); | |||
} | |||
@Test(expected = NullPointerException.class) | |||
public void constructor_throws_NPE_for_null_operator_argument() { | |||
new Condition(SOME_METRIC, null, null, null, false); | |||
new Condition(SOME_METRIC, null, null, null); | |||
} | |||
@Test | |||
@@ -51,7 +57,7 @@ public class ConditionTest { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Unsupported operator value: 'troloto'"); | |||
new Condition(SOME_METRIC, "troloto", null, null, false); | |||
new Condition(SOME_METRIC, "troloto", null, null); | |||
} | |||
@Test | |||
@@ -59,11 +65,10 @@ public class ConditionTest { | |||
String error = "error threshold"; | |||
String warning = "warning threshold"; | |||
Condition condition = new Condition(SOME_METRIC, SOME_OPERATOR, error, warning, true); | |||
Condition condition = new Condition(SOME_METRIC, SOME_OPERATOR, error, warning); | |||
assertThat(condition.getMetric()).isSameAs(SOME_METRIC); | |||
assertThat(condition.getOperator()).isSameAs(Condition.Operator.EQUALS); | |||
assertThat(condition.hasPeriod()).isTrue(); | |||
assertThat(condition.getErrorThreshold()).isEqualTo(error); | |||
assertThat(condition.getWarningThreshold()).isEqualTo(warning); | |||
} | |||
@@ -72,9 +77,7 @@ public class ConditionTest { | |||
public void all_fields_are_displayed_in_toString() { | |||
when(SOME_METRIC.toString()).thenReturn("metric1"); | |||
assertThat(new Condition(SOME_METRIC, SOME_OPERATOR, "error_l", "warn", true).toString()) | |||
.isEqualTo("Condition{metric=metric1, hasPeriod=true, operator=EQUALS, warningThreshold=warn, errorThreshold=error_l}"); | |||
assertThat(new Condition(SOME_METRIC, SOME_OPERATOR, "error_l", "warn").toString()) | |||
.isEqualTo("Condition{metric=metric1, operator=EQUALS, warningThreshold=warn, errorThreshold=error_l}"); | |||
} | |||
} |
@@ -24,10 +24,8 @@ import com.tngtech.java.junit.dataprovider.DataProvider; | |||
import com.tngtech.java.junit.dataprovider.DataProviderRunner; | |||
import com.tngtech.java.junit.dataprovider.UseDataProvider; | |||
import java.util.ArrayList; | |||
import java.util.Date; | |||
import java.util.List; | |||
import java.util.Locale; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.runner.RunWith; | |||
import org.sonar.api.i18n.I18n; | |||
@@ -35,9 +33,6 @@ import org.sonar.api.utils.Durations; | |||
import org.sonar.ce.task.projectanalysis.measure.Measure; | |||
import org.sonar.ce.task.projectanalysis.metric.Metric; | |||
import org.sonar.ce.task.projectanalysis.metric.MetricImpl; | |||
import org.sonar.ce.task.projectanalysis.period.Period; | |||
import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule; | |||
import org.sonar.core.timemachine.Periods; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
@@ -49,20 +44,16 @@ import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.WARN; | |||
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, false); | |||
private static final Condition EQ_10_CONDITION = new Condition(INT_METRIC, Condition.Operator.EQUALS.getDbValue(), "10", null); | |||
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"; | |||
@Rule | |||
public PeriodHolderRule periodsHolder = new PeriodHolderRule(); | |||
private I18n i18n = mock(I18n.class); | |||
private Durations durations = mock(Durations.class); | |||
private Periods periods = mock(Periods.class); | |||
private EvaluationResultTextConverter underTest = new EvaluationResultTextConverterImpl(i18n, durations, periods, periodsHolder); | |||
private EvaluationResultTextConverter underTest = new EvaluationResultTextConverterImpl(i18n, durations); | |||
@Test(expected = NullPointerException.class) | |||
public void evaluate_throws_NPE_if_Condition_arg_is_null() { | |||
@@ -98,7 +89,7 @@ public class EvaluationResultTextConverterTest { | |||
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, false); | |||
Condition condition = new Condition(INT_METRIC, operator.getDbValue(), ERROR_THRESHOLD, WARNING_THRESHOLD); | |||
assertThat(underTest.asText(condition, new EvaluationResult(level, null))) | |||
.isEqualTo(metricMsg + " " + toSign(operator) + " " + getThreshold(level)); | |||
@@ -116,56 +107,12 @@ public class EvaluationResultTextConverterTest { | |||
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, false); | |||
Condition condition = new Condition(SOME_VARIATION_METRIC, operator.getDbValue(), ERROR_THRESHOLD, WARNING_THRESHOLD); | |||
assertThat(underTest.asText(condition, new EvaluationResult(level, null))) | |||
.isEqualTo(metricMsg + " " + toSign(operator) + " " + getThreshold(level)); | |||
} | |||
@Test | |||
@UseDataProvider("all_operators_for_error_warning_levels") | |||
public void evaluate_adds_only_period_if_metric_starts_with_new_prefix(Condition.Operator operator, Measure.Level level) { | |||
String metricMsg = "trololo_metric_msg"; | |||
int periodIndex = 1; | |||
String periodLabel = "periodLabel"; | |||
when(i18n.message(Locale.ENGLISH, "metric." + SOME_VARIATION_METRIC.getKey() + ".name", SOME_VARIATION_METRIC.getName())) | |||
.thenReturn(metricMsg); | |||
Date date = new Date(); | |||
Period period = new Period(SOME_MODE, null, date.getTime(), SOME_ANALYSIS_UUID); | |||
periodsHolder.setPeriod(period); | |||
when(periods.label(period.getMode(), period.getModeParameter(), date)).thenReturn(periodLabel); | |||
Condition condition = new Condition(SOME_VARIATION_METRIC, operator.getDbValue(), ERROR_THRESHOLD, WARNING_THRESHOLD, true); | |||
assertThat(underTest.asText(condition, new EvaluationResult(level, null))) | |||
.isEqualTo(metricMsg + " " + toSign(operator) + " " + (getThreshold(level)) + " " + periodLabel); | |||
} | |||
@Test | |||
@UseDataProvider("all_operators_for_error_warning_levels") | |||
public void evaluate_adds_variation_and_period_if_metric_does_not_starts_with_variation_prefix(Condition.Operator operator, Measure.Level level) { | |||
String metricMsg = "trololo_metric_msg"; | |||
String variationMsg = "_variation_"; | |||
int periodIndex = 1; | |||
String periodLabel = "periodLabel"; | |||
when(i18n.message(Locale.ENGLISH, "metric." + INT_METRIC.getKey() + ".name", INT_METRIC.getName())) | |||
.thenReturn(metricMsg); | |||
when(i18n.message(Locale.ENGLISH, "variation", "variation")).thenReturn(variationMsg); | |||
Date date = new Date(); | |||
Period period = new Period(SOME_MODE, null, date.getTime(), SOME_ANALYSIS_UUID); | |||
periodsHolder.setPeriod(period); | |||
when(periods.label(period.getMode(), period.getModeParameter(), date)).thenReturn(periodLabel); | |||
Condition condition = new Condition(INT_METRIC, operator.getDbValue(), ERROR_THRESHOLD, WARNING_THRESHOLD, true); | |||
assertThat(underTest.asText(condition, new EvaluationResult(level, null))) | |||
.isEqualTo(metricMsg + " " + variationMsg + " " + toSign(operator) + " " + (getThreshold(level)) + " " + periodLabel); | |||
} | |||
private static String toSign(Condition.Operator operator) { | |||
switch (operator) { | |||
case EQUALS: |
@@ -53,7 +53,7 @@ public class QualityGateServiceImplTest { | |||
private static final long METRIC_ID_2 = 753; | |||
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").setPeriod(1) | |||
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"); | |||
@@ -67,6 +67,9 @@ public class QualityGateServiceImplTest { | |||
public void setUp() throws Exception { | |||
when(dbClient.qualityGateDao()).thenReturn(qualityGateDao); | |||
when(dbClient.gateConditionDao()).thenReturn(qualityGateConditionDao); | |||
when(METRIC_1.getKey()).thenReturn("metric"); | |||
when(METRIC_2.getKey()).thenReturn("new_metric"); | |||
} | |||
@Test | |||
@@ -101,8 +104,8 @@ public class QualityGateServiceImplTest { | |||
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(), true), | |||
new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold(), CONDITION_2.getWarningThreshold(), false)); | |||
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())); | |||
} | |||
@Test | |||
@@ -119,11 +122,11 @@ public class QualityGateServiceImplTest { | |||
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(), false)); | |||
new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold(), CONDITION_2.getWarningThreshold())); | |||
} | |||
@Test | |||
public void findById_of_hardcoded_short_living_branch_returns_hardcoded_qp() { | |||
public void findById_of_hardcoded_short_living_branch_returns_hardcoded_qg() { | |||
MetricImpl bugsMetric = mockMetricInRepository(CoreMetrics.BUGS_KEY); | |||
MetricImpl vulnerabilitiesMetric = mockMetricInRepository(CoreMetrics.VULNERABILITIES_KEY); | |||
MetricImpl codeSmellsMetric = mockMetricInRepository(CoreMetrics.CODE_SMELLS_KEY); | |||
@@ -137,10 +140,10 @@ public class QualityGateServiceImplTest { | |||
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, Condition::hasPeriod) | |||
.extracting(Condition::getMetric, Condition::getOperator, Condition::getErrorThreshold, Condition::getWarningThreshold) | |||
.containsOnly( | |||
tuple(openedIssueMetric, GREATER_THAN, "0", null, false), | |||
tuple(reOpenedIssueMetric, GREATER_THAN, "0", null, false)); | |||
tuple(openedIssueMetric, GREATER_THAN, "0", null), | |||
tuple(reOpenedIssueMetric, GREATER_THAN, "0", null)); | |||
} | |||
private MetricImpl mockMetricInRepository(String metricKey) { |
@@ -278,7 +278,7 @@ public class QualityGateMeasuresStepTest { | |||
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", true); | |||
Condition periodCondition = createEqualsCondition(INT_METRIC_1, null, "2"); | |||
qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(fixedCondition, periodCondition))); | |||
Measure measure = newMeasureBuilder().create(rawValue, null); | |||
@@ -292,31 +292,11 @@ public class QualityGateMeasuresStepTest { | |||
.hasQualityGateText(dumbResultTextAnswer(fixedCondition, ERROR, rawValue)); | |||
} | |||
@Test | |||
public void new_measure_has_WARN_level_of_all_conditions_for_a_specific_metric_if_its_the_worst() { | |||
int rawValue = 2; | |||
Condition fixedCondition = createEqualsCondition(INT_METRIC_1, "1", null); | |||
Condition periodCondition = createEqualsCondition(INT_METRIC_1, null, "2", true); | |||
qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(fixedCondition, periodCondition))); | |||
Measure measure = newMeasureBuilder() | |||
.setVariation(rawValue) | |||
.create(rawValue, null); | |||
measureRepository.addRawMeasure(PROJECT_REF, INT_METRIC_1_KEY, measure); | |||
underTest.execute(new TestComputationStepContext()); | |||
Optional<Measure> rawMeasure1 = measureRepository.getAddedRawMeasure(PROJECT_REF, INT_METRIC_1_KEY); | |||
assertThat(rawMeasure1.get()) | |||
.hasQualityGateLevel(WARN) | |||
.hasQualityGateText(dumbResultTextAnswer(periodCondition, WARN, rawValue)); | |||
} | |||
@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, true); | |||
Condition periodCondition = createEqualsCondition(INT_METRIC_1, "1", null); | |||
qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(fixedCondition, periodCondition))); | |||
Measure measure = newMeasureBuilder() | |||
@@ -341,11 +321,7 @@ public class QualityGateMeasuresStepTest { | |||
} | |||
private static Condition createEqualsCondition(Metric metric, @Nullable String errorThreshold, @Nullable String warningThreshold) { | |||
return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), errorThreshold, warningThreshold, false); | |||
} | |||
private static Condition createEqualsCondition(Metric metric, @Nullable String errorThreshold, @Nullable String warningThreshold, boolean hasPeriod) { | |||
return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), errorThreshold, warningThreshold, hasPeriod); | |||
return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), errorThreshold, warningThreshold); | |||
} | |||
private static MetricImpl createIntMetric(int index) { |
@@ -149,7 +149,7 @@ public class SmallChangesetQualityGateSpecialCaseTest { | |||
private QualityGateMeasuresStep.MetricEvaluationResult generateEvaluationResult(String metric, Measure.Level level) { | |||
Metric newCoverageMetric = metricRepository.getByKey(metric); | |||
Condition condition = new Condition(newCoverageMetric, "LT", "80", "90", true); | |||
Condition condition = new Condition(newCoverageMetric, "LT", "80", "90"); | |||
EvaluationResult evaluationResult = new EvaluationResult(level, mock(Comparable.class)); | |||
return new QualityGateMeasuresStep.MetricEvaluationResult(evaluationResult, condition); | |||
} |
@@ -148,8 +148,8 @@ public class WebhookPostTaskTest { | |||
condition.getMetricKey(), | |||
Condition.Operator.valueOf(condition.getOperator().name()), | |||
condition.getErrorThreshold(), | |||
condition.getWarningThreshold(), | |||
condition.isOnLeakPeriod()); | |||
condition.getWarningThreshold() | |||
); | |||
webQualityGate = EvaluatedQualityGate.newBuilder() | |||
.setQualityGate(new org.sonar.server.qualitygate.QualityGate(qualityGate.getId(), qualityGate.getName(), Collections.singleton(qgCondition))) | |||
.setStatus(Metric.Level.valueOf(qualityGate.getStatus().name())) |
@@ -91,8 +91,6 @@ public class QualityGateConditionDto { | |||
private String metricKey; | |||
private Integer period; | |||
private String operator; | |||
private String warningThreshold; | |||
@@ -140,16 +138,6 @@ public class QualityGateConditionDto { | |||
return this; | |||
} | |||
@CheckForNull | |||
public Integer getPeriod() { | |||
return period; | |||
} | |||
public QualityGateConditionDto setPeriod(@Nullable Integer period) { | |||
this.period = period; | |||
return this; | |||
} | |||
public String getOperator() { | |||
return operator; | |||
} |
@@ -4,15 +4,15 @@ | |||
<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, period, created_at, | |||
insert into quality_gate_conditions (qgate_id, metric_id, operator, value_error, value_warning, created_at, | |||
updated_at) | |||
values (#{qualityGateId}, #{metricId}, #{operator}, #{errorThreshold}, #{warningThreshold}, #{period}, #{createdAt}, | |||
values (#{qualityGateId}, #{metricId}, #{operator}, #{errorThreshold}, #{warningThreshold}, #{createdAt}, | |||
#{updatedAt}) | |||
</insert> | |||
<sql id="conditionColumns"> | |||
id, qgate_id as qualityGateId, metric_id as metricId, operator, value_warning as warningThreshold, value_error as | |||
errorThreshold, period, | |||
errorThreshold, | |||
created_at as createdAt, updated_at as updatedAt | |||
</sql> | |||
@@ -39,7 +39,6 @@ | |||
operator=#{operator}, | |||
value_warning=#{warningThreshold}, | |||
value_error=#{errorThreshold}, | |||
period=#{period}, | |||
updated_at=#{updatedAt} | |||
where id=#{id} | |||
</update> |
@@ -30,7 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
public class QualityGateConditionDaoTest { | |||
private static final String[] COLUMNS_WITHOUT_TIMESTAMPS = { | |||
"id", "qgate_id", "metric_id", "operator", "value_warning", "value_error", "period" | |||
"id", "qgate_id", "metric_id", "operator", "value_warning", "value_error" | |||
}; | |||
@Rule | |||
@@ -43,12 +43,12 @@ public class QualityGateConditionDaoTest { | |||
public void testInsert() { | |||
dbTester.prepareDbUnit(getClass(), "insert.xml"); | |||
QualityGateConditionDto newCondition = new QualityGateConditionDto() | |||
.setQualityGateId(1L).setMetricId(2L).setOperator("GT").setWarningThreshold("10").setErrorThreshold("20").setPeriod(3); | |||
.setQualityGateId(1L).setMetricId(2L).setOperator("GT").setWarningThreshold("10").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", "period"); | |||
dbTester.assertDbUnitTable(getClass(), "insert-result.xml", "quality_gate_conditions", "metric_id", "operator", "error_value", "warning_value"); | |||
assertThat(newCondition.getId()).isNotNull(); | |||
} | |||
@@ -67,7 +67,6 @@ public class QualityGateConditionDaoTest { | |||
assertThat(selectById.getId()).isNotNull().isNotEqualTo(0L); | |||
assertThat(selectById.getMetricId()).isEqualTo(2L); | |||
assertThat(selectById.getOperator()).isEqualTo("<"); | |||
assertThat(selectById.getPeriod()).isEqualTo(3); | |||
assertThat(selectById.getQualityGateId()).isEqualTo(1L); | |||
assertThat(selectById.getWarningThreshold()).isEqualTo("10"); | |||
assertThat(selectById.getErrorThreshold()).isEqualTo("20"); | |||
@@ -88,7 +87,7 @@ public class QualityGateConditionDaoTest { | |||
public void testUpdate() { | |||
dbTester.prepareDbUnit(getClass(), "selectForQualityGate.xml"); | |||
underTest.update(new QualityGateConditionDto().setId(1L).setMetricId(7L).setOperator(">").setPeriod(1).setWarningThreshold("50").setErrorThreshold("80"), dbSession); | |||
underTest.update(new QualityGateConditionDto().setId(1L).setMetricId(7L).setOperator(">").setWarningThreshold("50").setErrorThreshold("80"), dbSession); | |||
dbSession.commit(); | |||
dbTester.assertDbUnitTable(getClass(), "update-result.xml", "quality_gate_conditions", COLUMNS_WITHOUT_TIMESTAMPS); |
@@ -1,14 +1,9 @@ | |||
<dataset> | |||
<quality_gate_conditions id="1" qgate_id="1" metric_id="2" operator="<" value_warning="10" value_error="20" | |||
period="3"/> | |||
<quality_gate_conditions id="2" qgate_id="1" metric_id="3" operator="<" value_warning="10" value_error="20" | |||
period="[null]"/> | |||
<quality_gate_conditions id="3" qgate_id="1" metric_id="4" operator="<" value_warning="10" value_error="[null]" | |||
period="1"/> | |||
<quality_gate_conditions id="4" qgate_id="2" metric_id="5" operator="<" value_warning="[null]" value_error="20" | |||
period="3"/> | |||
<quality_gate_conditions id="5" qgate_id="2" metric_id="6" operator="<" value_warning="[null]" value_error="20" | |||
period="[null]"/> | |||
<quality_gate_conditions id="1" qgate_id="1" metric_id="2" operator="<" value_warning="10" value_error="20"/> | |||
<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"/> | |||
</dataset> |
@@ -1,14 +1,9 @@ | |||
<dataset> | |||
<quality_gate_conditions id="1" qgate_id="1" metric_id="7" operator=">" value_warning="50" value_error="80" | |||
period="1"/> | |||
<quality_gate_conditions id="2" qgate_id="1" metric_id="3" operator="<" value_warning="10" value_error="20" | |||
period="[null]"/> | |||
<quality_gate_conditions id="3" qgate_id="1" metric_id="4" operator="<" value_warning="10" value_error="[null]" | |||
period="1"/> | |||
<quality_gate_conditions id="4" qgate_id="2" metric_id="5" operator="<" value_warning="[null]" value_error="20" | |||
period="3"/> | |||
<quality_gate_conditions id="5" qgate_id="2" metric_id="6" operator="<" value_warning="[null]" value_error="20" | |||
period="[null]"/> | |||
<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"/> | |||
</dataset> |
@@ -42,11 +42,10 @@ public class Condition { | |||
private final boolean onLeakPeriod; | |||
public Condition(String metricKey, Operator operator, | |||
@Nullable String errorThreshold, @Nullable String warningThreshold, | |||
boolean onLeakPeriod) { | |||
@Nullable String errorThreshold, @Nullable String warningThreshold) { | |||
this.metricKey = requireNonNull(metricKey, "metricKey can't be null"); | |||
this.operator = requireNonNull(operator, "operator can't be null"); | |||
this.onLeakPeriod = onLeakPeriod; | |||
this.onLeakPeriod = metricKey.startsWith("new_"); | |||
this.errorThreshold = emptyToNull(errorThreshold); | |||
this.warningThreshold = emptyToNull(warningThreshold); | |||
} | |||
@@ -80,8 +79,7 @@ public class Condition { | |||
return false; | |||
} | |||
Condition condition = (Condition) o; | |||
return onLeakPeriod == condition.onLeakPeriod && | |||
Objects.equals(metricKey, condition.metricKey) && | |||
return Objects.equals(metricKey, condition.metricKey) && | |||
operator == condition.operator && | |||
Objects.equals(warningThreshold, condition.warningThreshold) && | |||
Objects.equals(errorThreshold, condition.errorThreshold); | |||
@@ -89,7 +87,7 @@ public class Condition { | |||
@Override | |||
public int hashCode() { | |||
return Objects.hash(metricKey, operator, warningThreshold, errorThreshold, onLeakPeriod); | |||
return Objects.hash(metricKey, operator, warningThreshold, errorThreshold); | |||
} | |||
@Override | |||
@@ -99,7 +97,6 @@ public class Condition { | |||
", operator=" + operator + | |||
", warningThreshold=" + toString(warningThreshold) + | |||
", errorThreshold=" + toString(errorThreshold) + | |||
", onLeakPeriod=" + onLeakPeriod + | |||
'}'; | |||
} | |||
@@ -128,14 +128,14 @@ class ConditionEvaluator { | |||
case DISTRIB: | |||
return measure.getStringValue().orElse(null); | |||
default: | |||
throw new IllegalArgumentException("Condition on leak period is not allowed for type " + measure.getType()); | |||
throw new IllegalArgumentException("Condition is not allowed for type " + measure.getType()); | |||
} | |||
} | |||
@CheckForNull | |||
private static Comparable getLeakValue(QualityGateEvaluator.Measure measure) { | |||
if (NUMERICAL_TYPES.contains(measure.getType())) { | |||
return measure.getLeakValue().isPresent() ? getNumericValue(measure.getType(), measure.getLeakValue().getAsDouble()) : null; | |||
return measure.getNewMetricValue().isPresent() ? getNumericValue(measure.getType(), measure.getNewMetricValue().getAsDouble()) : null; | |||
} | |||
throw new IllegalArgumentException("Condition on leak period is not allowed for type " + measure.getType()); |
@@ -55,6 +55,6 @@ public interface QualityGateEvaluator { | |||
Optional<String> getStringValue(); | |||
OptionalDouble getLeakValue(); | |||
OptionalDouble getNewMetricValue(); | |||
} | |||
} |
@@ -20,19 +20,13 @@ | |||
package org.sonar.server.qualitygate; | |||
import com.google.common.collect.ImmutableSet; | |||
import com.google.common.collect.Multimap; | |||
import java.util.Collection; | |||
import java.util.HashSet; | |||
import java.util.Map; | |||
import java.util.Optional; | |||
import java.util.Set; | |||
import java.util.function.Function; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.api.measures.Metric.Level; | |||
import org.sonar.core.util.stream.MoreCollectors; | |||
import org.sonar.server.qualitygate.EvaluatedCondition.EvaluationStatus; | |||
import static java.util.Objects.requireNonNull; | |||
import static org.sonar.core.util.stream.MoreCollectors.toEnumSet; | |||
public class QualityGateEvaluatorImpl implements QualityGateEvaluator { | |||
@@ -55,14 +49,9 @@ public class QualityGateEvaluatorImpl implements QualityGateEvaluator { | |||
.setQualityGate(gate); | |||
boolean isSmallChangeset = isSmallChangeset(measures); | |||
Multimap<String, Condition> conditionsPerMetric = gate.getConditions().stream() | |||
.collect(MoreCollectors.index(Condition::getMetricKey, Function.identity())); | |||
for (Map.Entry<String, Collection<Condition>> entry : conditionsPerMetric.asMap().entrySet()) { | |||
String metricKey = entry.getKey(); | |||
Collection<Condition> conditionsOnSameMetric = entry.getValue(); | |||
EvaluatedCondition evaluation = evaluateConditionsOnMetric(conditionsOnSameMetric, measures); | |||
gate.getConditions().forEach(condition -> { | |||
String metricKey = condition.getMetricKey(); | |||
EvaluatedCondition evaluation = ConditionEvaluator.evaluate(condition, measures); | |||
if (isSmallChangeset && evaluation.getStatus() != EvaluationStatus.OK && METRICS_TO_IGNORE_ON_SMALL_CHANGESETS.contains(metricKey)) { | |||
result.addCondition(new EvaluatedCondition(evaluation.getCondition(), EvaluationStatus.OK, evaluation.getValue().orElse(null))); | |||
@@ -70,7 +59,7 @@ public class QualityGateEvaluatorImpl implements QualityGateEvaluator { | |||
} else { | |||
result.addCondition(evaluation); | |||
} | |||
} | |||
}); | |||
result.setStatus(overallStatusOf(result.getEvaluatedConditions())); | |||
@@ -90,37 +79,15 @@ public class QualityGateEvaluatorImpl implements QualityGateEvaluator { | |||
private static boolean isSmallChangeset(Measures measures) { | |||
Optional<Measure> newLines = measures.get(CoreMetrics.NEW_LINES_KEY); | |||
return newLines.isPresent() && | |||
newLines.get().getLeakValue().isPresent() && | |||
newLines.get().getLeakValue().getAsDouble() < MAXIMUM_NEW_LINES_FOR_SMALL_CHANGESETS; | |||
} | |||
private static EvaluatedCondition evaluateConditionsOnMetric(Collection<Condition> conditionsOnSameMetric, Measures measures) { | |||
EvaluatedCondition leakEvaluation = null; | |||
EvaluatedCondition absoluteEvaluation = null; | |||
for (Condition condition : conditionsOnSameMetric) { | |||
if (condition.isOnLeakPeriod()) { | |||
leakEvaluation = ConditionEvaluator.evaluate(condition, measures); | |||
} else { | |||
absoluteEvaluation = ConditionEvaluator.evaluate(condition, measures); | |||
} | |||
} | |||
if (leakEvaluation == null) { | |||
return requireNonNull(absoluteEvaluation, "Evaluation of absolute value can't be null on conditions " + conditionsOnSameMetric); | |||
} | |||
if (absoluteEvaluation == null) { | |||
return requireNonNull(leakEvaluation, "Evaluation of leak value can't be null on conditions " + conditionsOnSameMetric); | |||
} | |||
// both conditions are present. Take the worse one. In case of equality, take | |||
// the one on the leak period | |||
if (absoluteEvaluation.getStatus().compareTo(leakEvaluation.getStatus()) > 0) { | |||
return absoluteEvaluation; | |||
} | |||
return leakEvaluation; | |||
newLines.get().getNewMetricValue().isPresent() && | |||
newLines.get().getNewMetricValue().getAsDouble() < MAXIMUM_NEW_LINES_FOR_SMALL_CHANGESETS; | |||
} | |||
private static Level overallStatusOf(Set<EvaluatedCondition> conditions) { | |||
Set<EvaluationStatus> statuses = conditions.stream().map(EvaluatedCondition::getStatus).collect(toEnumSet(EvaluationStatus.class)); | |||
Set<EvaluationStatus> statuses = conditions.stream() | |||
.map(EvaluatedCondition::getStatus) | |||
.collect(toEnumSet(EvaluationStatus.class)); | |||
if (statuses.contains(EvaluationStatus.ERROR)) { | |||
return Level.ERROR; | |||
} | |||
@@ -129,5 +96,4 @@ public class QualityGateEvaluatorImpl implements QualityGateEvaluator { | |||
} | |||
return Level.OK; | |||
} | |||
} |
@@ -34,12 +34,12 @@ public final class ShortLivingBranchQualityGate { | |||
public static final long ID = -1_963_456_987L; | |||
public static final String NAME = "Hardcoded short living branch quality gate"; | |||
public static final List<Condition> CONDITIONS = ImmutableList.of( | |||
new Condition(CoreMetrics.OPEN_ISSUES_KEY, OPERATOR_GREATER_THAN, "0", false), | |||
new Condition(CoreMetrics.REOPENED_ISSUES_KEY, OPERATOR_GREATER_THAN, "0", false)); | |||
new Condition(CoreMetrics.OPEN_ISSUES_KEY, OPERATOR_GREATER_THAN, "0"), | |||
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, false), | |||
new org.sonar.server.qualitygate.Condition(CoreMetrics.REOPENED_ISSUES_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0", null, false))); | |||
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))); | |||
private ShortLivingBranchQualityGate() { | |||
// prevents instantiation | |||
@@ -49,13 +49,11 @@ public final class ShortLivingBranchQualityGate { | |||
private final String metricKey; | |||
private final String operator; | |||
private final String errorThreshold; | |||
private final boolean onLeak; | |||
public Condition(String metricKey, String operator, String errorThreshold, boolean onLeak) { | |||
public Condition(String metricKey, String operator, String errorThreshold) { | |||
this.metricKey = metricKey; | |||
this.operator = operator; | |||
this.errorThreshold = errorThreshold; | |||
this.onLeak = onLeak; | |||
} | |||
public String getMetricKey() { | |||
@@ -74,9 +72,5 @@ public final class ShortLivingBranchQualityGate { | |||
public String getWarnThreshold() { | |||
return null; | |||
} | |||
public boolean isOnLeak() { | |||
return onLeak; | |||
} | |||
} | |||
} |
@@ -154,7 +154,6 @@ public class WebhookPayloadFactoryImpl implements WebhookPayloadFactory { | |||
evaluatedCondition.getValue().ifPresent(t -> writer.prop("value", t)); | |||
writer | |||
.prop(PROPERTY_STATUS, evaluatedCondition.getStatus().name()) | |||
.prop("onLeakPeriod", condition.isOnLeakPeriod()) | |||
.prop("errorThreshold", condition.getErrorThreshold().orElse(null)) | |||
.prop("warningThreshold", condition.getWarningThreshold().orElse(null)) | |||
.endObject(); |
@@ -130,7 +130,7 @@ public class ConditionEvaluatorTest { | |||
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, false); | |||
Condition condition = new Condition("foo", operator, errorThreshold, warningThreshold); | |||
EvaluatedCondition result = ConditionEvaluator.evaluate(condition, new FakeMeasures(measure)); | |||
@@ -144,7 +144,7 @@ public class ConditionEvaluatorTest { | |||
private void testOnLeak(QualityGateEvaluator.Measure measure, Condition.Operator operator, String errorThreshold, EvaluatedCondition.EvaluationStatus expectedStatus, | |||
@Nullable String expectedValue) { | |||
Condition condition = new Condition("foo", operator, errorThreshold, null, true); | |||
Condition condition = new Condition("new_foo", operator, errorThreshold, null); | |||
EvaluatedCondition result = ConditionEvaluator.evaluate(condition, new FakeMeasures(measure)); | |||
@@ -211,7 +211,7 @@ public class ConditionEvaluatorTest { | |||
} | |||
@Override | |||
public OptionalDouble getLeakValue() { | |||
public OptionalDouble getNewMetricValue() { | |||
return leakValue == null ? OptionalDouble.empty() : OptionalDouble.of(leakValue); | |||
} | |||
} |
@@ -31,19 +31,18 @@ public class ConditionTest { | |||
private static final Condition.Operator OPERATOR = Condition.Operator.EQUALS; | |||
private static final String ERROR_THRESHOLD = "2"; | |||
private static final String WARN_THRESHOLD = "4"; | |||
private static final boolean ON_LEAK_PERIOD = true; | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private Condition underTest = new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD, ON_LEAK_PERIOD); | |||
private Condition underTest = new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, WARN_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, ON_LEAK_PERIOD); | |||
new Condition(null, OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD); | |||
} | |||
@Test | |||
@@ -51,19 +50,19 @@ public class ConditionTest { | |||
expectedException.expect(NullPointerException.class); | |||
expectedException.expectMessage("operator can't be null"); | |||
new Condition(METRIC_KEY, null, ERROR_THRESHOLD, WARN_THRESHOLD, ON_LEAK_PERIOD); | |||
new Condition(METRIC_KEY, null, ERROR_THRESHOLD, WARN_THRESHOLD); | |||
} | |||
@Test | |||
public void errorThreshold_can_be_null() { | |||
Condition underTest = new Condition(METRIC_KEY, OPERATOR, null, WARN_THRESHOLD, ON_LEAK_PERIOD); | |||
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, ON_LEAK_PERIOD); | |||
Condition underTest = new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, null); | |||
assertThat(underTest.getWarningThreshold()).isEmpty(); | |||
} | |||
@@ -74,20 +73,19 @@ public class ConditionTest { | |||
assertThat(underTest.getOperator()).isEqualTo(OPERATOR); | |||
assertThat(underTest.getErrorThreshold()).contains(ERROR_THRESHOLD); | |||
assertThat(underTest.getWarningThreshold()).contains(WARN_THRESHOLD); | |||
assertThat(underTest.isOnLeakPeriod()).isEqualTo(ON_LEAK_PERIOD); | |||
} | |||
@Test | |||
public void toString_is_override() { | |||
assertThat(underTest.toString()) | |||
.isEqualTo("Condition{metricKey='metric_key', operator=EQUALS, warningThreshold='4', errorThreshold='2', onLeakPeriod=true}"); | |||
.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, false); | |||
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, onLeakPeriod=false}"); | |||
.isEqualTo("Condition{metricKey='metric_key', operator=LESS_THAN, warningThreshold=null, errorThreshold=null}"); | |||
} | |||
@Test | |||
@@ -95,17 +93,16 @@ public class ConditionTest { | |||
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, ON_LEAK_PERIOD)); | |||
assertThat(underTest).isNotEqualTo(new Condition("other_metric_key", OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD, ON_LEAK_PERIOD)); | |||
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)); | |||
Arrays.stream(Condition.Operator.values()) | |||
.filter(s -> !OPERATOR.equals(s)) | |||
.forEach(otherOperator -> assertThat(underTest) | |||
.isNotEqualTo(new Condition(METRIC_KEY, otherOperator, ERROR_THRESHOLD, WARN_THRESHOLD, ON_LEAK_PERIOD))); | |||
assertThat(underTest).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, null, WARN_THRESHOLD, ON_LEAK_PERIOD)); | |||
assertThat(underTest).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, "other_error_threshold", WARN_THRESHOLD, ON_LEAK_PERIOD)); | |||
assertThat(underTest).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, null, ON_LEAK_PERIOD)); | |||
assertThat(underTest).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, "other_warn_threshold", ON_LEAK_PERIOD)); | |||
assertThat(underTest).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD, !ON_LEAK_PERIOD)); | |||
.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")); | |||
} | |||
@Test | |||
@@ -113,16 +110,15 @@ public class ConditionTest { | |||
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, ON_LEAK_PERIOD).hashCode()); | |||
assertThat(underTest.hashCode()).isNotEqualTo(new Condition("other_metric_key", OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD, ON_LEAK_PERIOD).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()); | |||
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, ON_LEAK_PERIOD).hashCode())); | |||
assertThat(underTest.hashCode()).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, null, WARN_THRESHOLD, ON_LEAK_PERIOD).hashCode()); | |||
assertThat(underTest.hashCode()).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, "other_error_threshold", WARN_THRESHOLD, ON_LEAK_PERIOD).hashCode()); | |||
assertThat(underTest.hashCode()).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, null, ON_LEAK_PERIOD).hashCode()); | |||
assertThat(underTest.hashCode()).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, "other_warn_threshold", ON_LEAK_PERIOD).hashCode()); | |||
assertThat(underTest.hashCode()).isNotEqualTo(new Condition(METRIC_KEY, OPERATOR, ERROR_THRESHOLD, WARN_THRESHOLD, !ON_LEAK_PERIOD).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()); | |||
} | |||
} |
@@ -29,7 +29,7 @@ import static org.sonar.server.qualitygate.EvaluatedCondition.EvaluationStatus.O | |||
import static org.sonar.server.qualitygate.EvaluatedCondition.EvaluationStatus.WARN; | |||
public class EvaluatedConditionTest { | |||
private static final Condition CONDITION_1 = new Condition("metricKey", EQUALS, "2", "4", false); | |||
private static final Condition CONDITION_1 = new Condition("metricKey", EQUALS, "2", "4"); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@@ -71,7 +71,7 @@ public class EvaluatedConditionTest { | |||
@Test | |||
public void override_toString() { | |||
assertThat(underTest.toString()).isEqualTo("EvaluatedCondition{condition=" + | |||
"Condition{metricKey='metricKey', operator=EQUALS, warningThreshold='4', errorThreshold='2', onLeakPeriod=false}, " + | |||
"Condition{metricKey='metricKey', operator=EQUALS, warningThreshold='4', errorThreshold='2'}, " + | |||
"status=WARN, value='value'}"); | |||
} | |||
@@ -80,7 +80,7 @@ public class EvaluatedConditionTest { | |||
EvaluatedCondition underTest = new EvaluatedCondition(CONDITION_1, WARN, null); | |||
assertThat(underTest.toString()).isEqualTo("EvaluatedCondition{condition=" + | |||
"Condition{metricKey='metricKey', operator=EQUALS, warningThreshold='4', errorThreshold='2', onLeakPeriod=false}, " + | |||
"Condition{metricKey='metricKey', operator=EQUALS, warningThreshold='4', errorThreshold='2'}, " + | |||
"status=WARN, value=null}"); | |||
} | |||
@@ -90,7 +90,7 @@ public class EvaluatedConditionTest { | |||
assertThat(underTest).isEqualTo(new EvaluatedCondition(CONDITION_1, WARN, "value")); | |||
assertThat(underTest).isNotEqualTo(null); | |||
assertThat(underTest).isNotEqualTo(new Object()); | |||
assertThat(underTest).isNotEqualTo(new EvaluatedCondition(new Condition("other_metric", EQUALS, "a", "b", true), WARN, "value")); | |||
assertThat(underTest).isNotEqualTo(new EvaluatedCondition(new Condition("other_metric", EQUALS, "a", "b"), WARN, "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")); | |||
@@ -102,7 +102,7 @@ public class EvaluatedConditionTest { | |||
assertThat(underTest.hashCode()).isEqualTo(new EvaluatedCondition(CONDITION_1, WARN, "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", true), WARN, "value").hashCode()); | |||
assertThat(underTest.hashCode()).isNotEqualTo(new EvaluatedCondition(new Condition("other_metric", EQUALS, "a", "b"), WARN, "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()); |
@@ -36,8 +36,8 @@ public class EvaluatedQualityGateTest { | |||
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", true); | |||
private static final Condition CONDITION_2 = new Condition("metric_key_2", Condition.Operator.GREATER_THAN, "6", "12", false); | |||
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 QualityGate ONE_CONDITION_QUALITY_GATE = new QualityGate(QUALITY_GATE_ID, QUALITY_GATE_NAME, singleton(CONDITION_1)); | |||
@Rule | |||
@@ -74,7 +74,7 @@ public class EvaluatedQualityGateTest { | |||
expectedException.expect(NullPointerException.class); | |||
expectedException.expectMessage("status can't be null"); | |||
builder.addCondition(new Condition("metric_key", Condition.Operator.LESS_THAN, "2", "4", true), null, "a_value"); | |||
builder.addCondition(new Condition("metric_key", Condition.Operator.LESS_THAN, "2", "4"), null, "a_value"); | |||
} | |||
@Test |
@@ -0,0 +1,64 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.qualitygate; | |||
import com.google.common.collect.ImmutableSet; | |||
import java.util.Set; | |||
import java.util.stream.Collectors; | |||
import org.junit.Test; | |||
import org.sonar.api.measures.Metric; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import static org.sonar.api.measures.CoreMetrics.NEW_LINES_KEY; | |||
public class QualityGateEvaluatorImplTest { | |||
private final QualityGateEvaluator underTest = new QualityGateEvaluatorImpl(); | |||
@Test | |||
public void getMetricKeys_includes_by_default_new_lines() { | |||
QualityGate gate = mock(QualityGate.class); | |||
assertThat(underTest.getMetricKeys(gate)).containsExactly(NEW_LINES_KEY); | |||
} | |||
@Test | |||
public void getMetricKeys_includes_metrics_from_qgate() { | |||
Set<String> metricKeys = ImmutableSet.of("foo", "bar", "baz"); | |||
Set<Condition> conditions = metricKeys.stream().map(key -> { | |||
Condition condition = mock(Condition.class); | |||
when(condition.getMetricKey()).thenReturn(key); | |||
return condition; | |||
}).collect(Collectors.toSet()); | |||
QualityGate gate = mock(QualityGate.class); | |||
when(gate.getConditions()).thenReturn(conditions); | |||
assertThat(underTest.getMetricKeys(gate)).containsAll(metricKeys); | |||
} | |||
@Test | |||
public void evaluate_is_OK_for_empty_qgate() { | |||
QualityGate gate = mock(QualityGate.class); | |||
QualityGateEvaluator.Measures measures = mock(QualityGateEvaluator.Measures.class); | |||
EvaluatedQualityGate evaluatedQualityGate = underTest.evaluate(gate, measures); | |||
assertThat(evaluatedQualityGate.getStatus()).isEqualTo(Metric.Level.OK); | |||
} | |||
} |
@@ -35,8 +35,8 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
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", false); | |||
private static final Condition CONDITION_2 = new Condition("m2", Condition.Operator.LESS_THAN, "2", "4", true); | |||
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"); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@@ -74,10 +74,10 @@ public class QualityGateTest { | |||
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, false)), | |||
.mapToObj(i -> new Condition("m_before_" + i, Condition.Operator.EQUALS, null, null)), | |||
Stream.of((Condition) null), | |||
IntStream.range(0, random.nextInt(5)) | |||
.mapToObj(i -> new Condition("m_after_" + i, Condition.Operator.EQUALS, null, null, false))) | |||
.mapToObj(i -> new Condition("m_after_" + i, Condition.Operator.EQUALS, null, null))) | |||
.flatMap(s -> s) | |||
.collect(Collectors.toSet()); | |||
@@ -99,7 +99,7 @@ public class QualityGateTest { | |||
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', onLeakPeriod=true}" + | |||
"Condition{metricKey='m2', operator=LESS_THAN, warningThreshold='4', errorThreshold='2'}" + | |||
"]}"); | |||
} | |||
@@ -115,7 +115,7 @@ public class QualityGateTest { | |||
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", false)))); | |||
new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_1, CONDITION_2, new Condition("new", Condition.Operator.GREATER_THAN, "a", "b")))); | |||
} | |||
@Test | |||
@@ -130,6 +130,6 @@ public class QualityGateTest { | |||
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", false))).hashCode()); | |||
new QualityGate(QUALIGATE_ID, QUALIGATE_NAME, ImmutableSet.of(CONDITION_1, CONDITION_2, new Condition("new", Condition.Operator.GREATER_THAN, "a", "b"))).hashCode()); | |||
} | |||
} |
@@ -31,10 +31,10 @@ public class ShortLivingBranchQualityGateTest { | |||
@Test | |||
public void defines_short_living_branches_hardcoded_quality_gate_conditions() { | |||
assertThat(ShortLivingBranchQualityGate.CONDITIONS) | |||
.extracting(Condition::getMetricKey, Condition::getOperator, Condition::getErrorThreshold, Condition::getWarnThreshold, Condition::isOnLeak) | |||
.extracting(Condition::getMetricKey, Condition::getOperator, Condition::getErrorThreshold, Condition::getWarnThreshold) | |||
.containsExactly( | |||
tuple(CoreMetrics.OPEN_ISSUES_KEY, "GT", "0", null, false), | |||
tuple(CoreMetrics.REOPENED_ISSUES_KEY, "GT", "0", null, false)); | |||
tuple(CoreMetrics.OPEN_ISSUES_KEY, "GT", "0", null), | |||
tuple(CoreMetrics.REOPENED_ISSUES_KEY, "GT", "0", null)); | |||
} | |||
} |
@@ -57,7 +57,7 @@ public class WebhookPayloadFactoryImplTest { | |||
@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", true); | |||
Condition condition = new Condition("coverage", Condition.Operator.GREATER_THAN, "70.0", "75.0"); | |||
EvaluatedQualityGate gate = EvaluatedQualityGate.newBuilder() | |||
.setQualityGate(new QualityGate("G1", "Gate One", singleton(condition))) | |||
.setStatus(Metric.Level.WARN) | |||
@@ -88,7 +88,6 @@ public class WebhookPayloadFactoryImplTest { | |||
" \"operator\": \"GREATER_THAN\"," + | |||
" \"value\": \"74.0\"," + | |||
" \"status\": \"WARN\"," + | |||
" \"onLeakPeriod\": true," + | |||
" \"errorThreshold\": \"70.0\"," + | |||
" \"warningThreshold\": \"75.0\"" + | |||
" }" + | |||
@@ -103,7 +102,7 @@ public class WebhookPayloadFactoryImplTest { | |||
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", false); | |||
Condition condition = new Condition("coverage", Condition.Operator.GREATER_THAN, "70.0", "75.0"); | |||
EvaluatedQualityGate gate = EvaluatedQualityGate.newBuilder() | |||
.setQualityGate(new QualityGate("G1", "Gate One", singleton(condition))) | |||
.setStatus(Metric.Level.WARN) | |||
@@ -133,7 +132,6 @@ public class WebhookPayloadFactoryImplTest { | |||
" \"metric\": \"coverage\"," + | |||
" \"operator\": \"GREATER_THAN\"," + | |||
" \"status\": \"NO_VALUE\"," + | |||
" \"onLeakPeriod\": false," + | |||
" \"errorThreshold\": \"70.0\"," + | |||
" \"warningThreshold\": \"75.0\"" + | |||
" }" + |
@@ -22,7 +22,6 @@ package org.sonar.server.measure.live; | |||
import java.util.Collection; | |||
import java.util.HashSet; | |||
import java.util.Map; | |||
import java.util.Objects; | |||
import java.util.Optional; | |||
import java.util.OptionalDouble; | |||
import java.util.Set; | |||
@@ -81,8 +80,7 @@ public class LiveQualityGateComputerImpl implements LiveQualityGateComputer { | |||
Set<Condition> conditions = conditionDtos.stream().map(conditionDto -> { | |||
String metricKey = metricsById.get((int) conditionDto.getMetricId()).getKey(); | |||
Condition.Operator operator = Condition.Operator.fromDbValue(conditionDto.getOperator()); | |||
boolean onLeak = Objects.equals(conditionDto.getPeriod(), 1); | |||
return new Condition(metricKey, operator, conditionDto.getErrorThreshold(), conditionDto.getWarningThreshold(), onLeak); | |||
return new Condition(metricKey, operator, conditionDto.getErrorThreshold(), conditionDto.getWarningThreshold()); | |||
}).collect(toHashSet(conditionDtos.size())); | |||
return new QualityGate(String.valueOf(gateDto.getId()), gateDto.getName(), conditions); | |||
@@ -144,7 +142,7 @@ public class LiveQualityGateComputerImpl implements LiveQualityGateComputer { | |||
} | |||
@Override | |||
public OptionalDouble getLeakValue() { | |||
public OptionalDouble getNewMetricValue() { | |||
if (dto.getVariation() == null) { | |||
return OptionalDouble.empty(); | |||
} |
@@ -26,7 +26,6 @@ import java.util.Objects; | |||
import java.util.stream.Collectors; | |||
import javax.annotation.Nullable; | |||
import org.apache.commons.lang.BooleanUtils; | |||
import org.apache.commons.lang.ObjectUtils; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.api.measures.Metric.ValueType; | |||
import org.sonar.db.DbClient; | |||
@@ -61,34 +60,31 @@ public class QualityGateConditionsUpdater { | |||
} | |||
public QualityGateConditionDto createCondition(DbSession dbSession, QualityGateDto qualityGate, String metricKey, String operator, | |||
@Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period) { | |||
@Nullable String warningThreshold, @Nullable String errorThreshold) { | |||
MetricDto metric = getNonNullMetric(dbSession, metricKey); | |||
validateCondition(metric, operator, warningThreshold, errorThreshold, period); | |||
checkConditionDoesNotAlreadyExistOnSameMetricAndPeriod(getConditions(dbSession, qualityGate.getId(), null), metric, period); | |||
validateCondition(metric, operator, warningThreshold, 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) | |||
.setPeriod(period); | |||
.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, @Nullable Integer period) { | |||
@Nullable String warningThreshold, @Nullable String errorThreshold) { | |||
MetricDto metric = getNonNullMetric(dbSession, metricKey); | |||
validateCondition(metric, operator, warningThreshold, errorThreshold, period); | |||
checkConditionDoesNotAlreadyExistOnSameMetricAndPeriod(getConditions(dbSession, condition.getQualityGateId(), condition.getId()), metric, period); | |||
validateCondition(metric, operator, warningThreshold, errorThreshold); | |||
condition | |||
.setMetricId(metric.getId()) | |||
.setMetricKey(metric.getKey()) | |||
.setOperator(operator) | |||
.setWarningThreshold(warningThreshold) | |||
.setErrorThreshold(errorThreshold) | |||
.setPeriod(period); | |||
.setErrorThreshold(errorThreshold); | |||
dbClient.gateConditionDao().update(condition, dbSession); | |||
return condition; | |||
} | |||
@@ -101,26 +97,19 @@ public class QualityGateConditionsUpdater { | |||
return metric; | |||
} | |||
private Collection<QualityGateConditionDto> getConditions(DbSession dbSession, long qGateId, @Nullable Long conditionId) { | |||
Collection<QualityGateConditionDto> conditions = dbClient.gateConditionDao().selectForQualityGate(dbSession, qGateId); | |||
if (conditionId == null) { | |||
return conditions; | |||
} | |||
return dbClient.gateConditionDao().selectForQualityGate(dbSession, qGateId).stream() | |||
.filter(condition -> condition.getId() != conditionId) | |||
.collect(Collectors.toList()); | |||
private Collection<QualityGateConditionDto> getConditions(DbSession dbSession, long qGateId) { | |||
return dbClient.gateConditionDao().selectForQualityGate(dbSession, qGateId); | |||
} | |||
private static void validateCondition(MetricDto metric, String operator, @Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period) { | |||
private static void validateCondition(MetricDto metric, String operator, @Nullable String warningThreshold, @Nullable String errorThreshold) { | |||
List<String> errors = new ArrayList<>(); | |||
validateMetric(metric, errors); | |||
checkOperator(metric, operator, errors); | |||
checkThresholds(warningThreshold, errorThreshold, errors); | |||
checkPeriod(metric, period, errors); | |||
validateThresholdValues(metric, warningThreshold, errors); | |||
validateThresholdValues(metric, errorThreshold, errors); | |||
checkRatingMetric(metric, warningThreshold, errorThreshold, period, errors); | |||
checkRatingMetric(metric, warningThreshold, errorThreshold, errors); | |||
checkRequest(errors.isEmpty(), errors); | |||
} | |||
@@ -145,23 +134,13 @@ public class QualityGateConditionsUpdater { | |||
check(warningThreshold != null || errorThreshold != null, errors, "At least one threshold (warning, error) must be set."); | |||
} | |||
private static void checkPeriod(MetricDto metric, @Nullable Integer period, List<String> errors) { | |||
if (period == null) { | |||
check(!metric.getKey().startsWith("new_"), errors, "A period must be selected for differential metrics."); | |||
} else { | |||
check(period == 1, errors, "The only valid quality gate period is 1, the leak period."); | |||
} | |||
} | |||
private static void checkConditionDoesNotAlreadyExistOnSameMetricAndPeriod(Collection<QualityGateConditionDto> conditions, MetricDto metric, @Nullable final Integer period) { | |||
private static void checkConditionDoesNotExistOnSameMetric(Collection<QualityGateConditionDto> conditions, MetricDto metric) { | |||
if (conditions.isEmpty()) { | |||
return; | |||
} | |||
boolean conditionExists = conditions.stream().anyMatch(c -> c.getMetricId() == metric.getId() && ObjectUtils.equals(c.getPeriod(), period)); | |||
checkRequest(!conditionExists, period == null | |||
? format("Condition on metric '%s' already exists.", metric.getShortName()) | |||
: format("Condition on metric '%s' over leak period already exists.", metric.getShortName())); | |||
boolean conditionExists = conditions.stream().anyMatch(c -> c.getMetricId() == metric.getId()); | |||
checkRequest(!conditionExists, format("Condition on metric '%s' already exists.", metric.getShortName())); | |||
} | |||
private static void validateThresholdValues(MetricDto metric, @Nullable String value, List<String> errors) { | |||
@@ -195,16 +174,13 @@ public class QualityGateConditionsUpdater { | |||
} | |||
} | |||
private static void checkRatingMetric(MetricDto metric, @Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period, List<String> errors) { | |||
private static void checkRatingMetric(MetricDto metric, @Nullable String warningThreshold, @Nullable 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 (period != null && !metric.getKey().startsWith("new_")) { | |||
errors.add(format("The metric '%s' cannot be used on the leak period", metric.getShortName())); | |||
} | |||
if (!isValidRating(warningThreshold)) { | |||
addInvalidRatingError(warningThreshold, errors); | |||
return; |
@@ -49,9 +49,6 @@ public class QualityGateConverter { | |||
JsonObject result = new JsonObject(); | |||
result.addProperty("metric", condition.getMetricKey()); | |||
result.addProperty("op", condition.getOperator().getDbValue()); | |||
if (condition.isOnLeakPeriod()) { | |||
result.addProperty("period", 1); | |||
} | |||
condition.getWarningThreshold().ifPresent(t -> result.addProperty("warning", t)); | |||
condition.getErrorThreshold().ifPresent(t -> result.addProperty("error", t)); | |||
evaluatedCondition.getValue().ifPresent(v -> result.addProperty("actual", v)); |
@@ -60,7 +60,7 @@ public class QualityGateUpdater { | |||
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()).setPeriod(sourceCondition.getPeriod()), | |||
.setWarningThreshold(sourceCondition.getWarningThreshold()).setErrorThreshold(sourceCondition.getErrorThreshold()), | |||
dbSession); | |||
} | |||
@@ -56,15 +56,14 @@ public class RegisterQualityGates implements Startable { | |||
private static final Logger LOGGER = Loggers.get(RegisterQualityGates.class); | |||
private static final String BUILTIN_QUALITY_GATE_NAME = "Sonar way"; | |||
private static final int LEAK_PERIOD = 1; | |||
private static final String A_RATING = Integer.toString(Rating.A.getIndex()); | |||
private static final List<QualityGateCondition> QUALITY_GATE_CONDITIONS = asList( | |||
new QualityGateCondition().setMetricKey(NEW_SECURITY_RATING_KEY).setOperator(OPERATOR_GREATER_THAN).setPeriod(LEAK_PERIOD).setErrorThreshold(A_RATING), | |||
new QualityGateCondition().setMetricKey(NEW_RELIABILITY_RATING_KEY).setOperator(OPERATOR_GREATER_THAN).setPeriod(LEAK_PERIOD).setErrorThreshold(A_RATING), | |||
new QualityGateCondition().setMetricKey(NEW_MAINTAINABILITY_RATING_KEY).setOperator(OPERATOR_GREATER_THAN).setPeriod(LEAK_PERIOD).setErrorThreshold(A_RATING), | |||
new QualityGateCondition().setMetricKey(NEW_COVERAGE_KEY).setOperator(OPERATOR_LESS_THAN).setPeriod(LEAK_PERIOD).setErrorThreshold("80"), | |||
new QualityGateCondition().setMetricKey(NEW_DUPLICATED_LINES_DENSITY_KEY).setOperator(OPERATOR_GREATER_THAN).setPeriod(LEAK_PERIOD).setErrorThreshold("3")); | |||
new QualityGateCondition().setMetricKey(NEW_SECURITY_RATING_KEY).setOperator(OPERATOR_GREATER_THAN).setErrorThreshold(A_RATING), | |||
new QualityGateCondition().setMetricKey(NEW_RELIABILITY_RATING_KEY).setOperator(OPERATOR_GREATER_THAN).setErrorThreshold(A_RATING), | |||
new QualityGateCondition().setMetricKey(NEW_MAINTAINABILITY_RATING_KEY).setOperator(OPERATOR_GREATER_THAN).setErrorThreshold(A_RATING), | |||
new QualityGateCondition().setMetricKey(NEW_COVERAGE_KEY).setOperator(OPERATOR_LESS_THAN).setErrorThreshold("80"), | |||
new QualityGateCondition().setMetricKey(NEW_DUPLICATED_LINES_DENSITY_KEY).setOperator(OPERATOR_GREATER_THAN).setErrorThreshold("3")); | |||
private final DbClient dbClient; | |||
private final QualityGateConditionsUpdater qualityGateConditionsUpdater; | |||
@@ -122,16 +121,16 @@ public class RegisterQualityGates implements Startable { | |||
// Those conditions must be deleted | |||
List<QualityGateCondition> qgConditionsToBeDeleted = new ArrayList<>(qualityGateConditions); | |||
qgConditionsToBeDeleted.removeAll(QUALITY_GATE_CONDITIONS); | |||
qgConditionsToBeDeleted.stream() | |||
qgConditionsToBeDeleted | |||
.forEach(qgc -> qualityGateConditionDao.delete(qgc.toQualityGateDto(builtin.getId()), dbSession)); | |||
// Find all conditions that are not present in qualityGateConditions | |||
// Those conditions must be created | |||
List<QualityGateCondition> qgConditionsToBeCreated = new ArrayList<>(QUALITY_GATE_CONDITIONS); | |||
qgConditionsToBeCreated.removeAll(qualityGateConditions); | |||
qgConditionsToBeCreated.stream() | |||
qgConditionsToBeCreated | |||
.forEach(qgc -> qualityGateConditionsUpdater.createCondition(dbSession, builtin, qgc.getMetricKey(), qgc.getOperator(), qgc.getWarningThreshold(), | |||
qgc.getErrorThreshold(), qgc.getPeriod())); | |||
qgc.getErrorThreshold())); | |||
if (!qgConditionsToBeCreated.isEmpty() || !qgConditionsToBeDeleted.isEmpty()) { | |||
LOGGER.info("Built-in quality gate's conditions of [{}] has been updated", BUILTIN_QUALITY_GATE_NAME); | |||
@@ -155,7 +154,6 @@ public class RegisterQualityGates implements Startable { | |||
private static class QualityGateCondition { | |||
private Long id; | |||
private String metricKey; | |||
private Integer period; | |||
private String operator; | |||
private String warningThreshold; | |||
private String errorThreshold; | |||
@@ -165,7 +163,6 @@ public class RegisterQualityGates implements Startable { | |||
.setId(qualityGateConditionDto.getId()) | |||
.setMetricKey(mapping.get(qualityGateConditionDto.getMetricId())) | |||
.setOperator(qualityGateConditionDto.getOperator()) | |||
.setPeriod(qualityGateConditionDto.getPeriod()) | |||
.setErrorThreshold(qualityGateConditionDto.getErrorThreshold()) | |||
.setWarningThreshold(qualityGateConditionDto.getWarningThreshold()); | |||
} | |||
@@ -189,15 +186,6 @@ public class RegisterQualityGates implements Startable { | |||
return this; | |||
} | |||
public Integer getPeriod() { | |||
return period; | |||
} | |||
public QualityGateCondition setPeriod(Integer period) { | |||
this.period = period; | |||
return this; | |||
} | |||
public String getOperator() { | |||
return operator; | |||
} | |||
@@ -232,7 +220,6 @@ public class RegisterQualityGates implements Startable { | |||
.setId(id) | |||
.setMetricKey(metricKey) | |||
.setOperator(operator) | |||
.setPeriod(period) | |||
.setErrorThreshold(errorThreshold) | |||
.setWarningThreshold(warningThreshold) | |||
.setQualityGateId(qualityGateId); | |||
@@ -249,7 +236,6 @@ public class RegisterQualityGates implements Startable { | |||
} | |||
QualityGateCondition that = (QualityGateCondition) o; | |||
return Objects.equals(metricKey, that.metricKey) && | |||
Objects.equals(period, that.period) && | |||
Objects.equals(operator, that.operator) && | |||
Objects.equals(warningThreshold, that.warningThreshold) && | |||
Objects.equals(errorThreshold, that.errorThreshold); | |||
@@ -258,7 +244,7 @@ public class RegisterQualityGates implements Startable { | |||
// id does not belongs to hashcode to be able to be compared with builtin | |||
@Override | |||
public int hashCode() { | |||
return Objects.hash(metricKey, period, operator, warningThreshold, errorThreshold); | |||
return Objects.hash(metricKey, operator, warningThreshold, errorThreshold); | |||
} | |||
} | |||
} |
@@ -38,7 +38,6 @@ import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ERR | |||
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_PERIOD; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_WARNING; | |||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||
@@ -81,20 +80,18 @@ public class CreateConditionAction implements QualityGatesWsAction { | |||
String operator = request.mandatoryParam(PARAM_OPERATOR); | |||
String warning = request.param(PARAM_WARNING); | |||
String error = request.param(PARAM_ERROR); | |||
Integer period = request.paramAsInt(PARAM_PERIOD); | |||
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), period); | |||
QualityGateConditionDto condition = qualityGateConditionsUpdater.createCondition(dbSession, qualityGate, metric, operator, emptyToNull(warning), emptyToNull(error)); | |||
CreateConditionResponse.Builder createConditionResponse = CreateConditionResponse.newBuilder() | |||
.setId(condition.getId()) | |||
.setMetric(condition.getMetricKey()) | |||
.setOp(condition.getOperator()); | |||
setNullable(condition.getWarningThreshold(), createConditionResponse::setWarning); | |||
setNullable(condition.getErrorThreshold(), createConditionResponse::setError); | |||
setNullable(condition.getPeriod(), createConditionResponse::setPeriod); | |||
writeProtobuf(createConditionResponse.build(), request, response); | |||
dbSession.commit(); | |||
} |
@@ -30,7 +30,6 @@ import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.CONTROLLE | |||
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_PERIOD; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_WARNING; | |||
public class QualityGatesWs implements WebService { | |||
@@ -85,10 +84,6 @@ public class QualityGatesWs implements WebService { | |||
.setExampleValue(QualityGateConditionDto.OPERATOR_EQUALS) | |||
.setPossibleValues(QualityGateConditionDto.ALL_OPERATORS); | |||
action.createParam(PARAM_PERIOD) | |||
.setDescription("Condition period. If not set, the absolute value is considered.") | |||
.setPossibleValues("1"); | |||
action.createParam(PARAM_WARNING) | |||
.setMaximumLength(CONDITION_MAX_LENGTH) | |||
.setDescription("Condition warning threshold") |
@@ -40,7 +40,6 @@ public class QualityGatesWsParameters { | |||
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_PERIOD = "period"; | |||
public static final String PARAM_OPERATOR = "op"; | |||
public static final String PARAM_METRIC = "metric"; | |||
public static final String PARAM_GATE_ID = "gateId"; |
@@ -142,7 +142,6 @@ public class ShowAction implements QualityGatesWsAction { | |||
.setId(condition.getId()) | |||
.setMetric(metric.getKey()) | |||
.setOp(condition.getOperator()); | |||
setNullable(condition.getPeriod(), builder::setPeriod); | |||
setNullable(condition.getErrorThreshold(), builder::setError); | |||
setNullable(condition.getWarningThreshold(), builder::setWarning); | |||
return builder.build(); |
@@ -39,7 +39,6 @@ import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ERR | |||
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_PERIOD; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_WARNING; | |||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||
@@ -81,7 +80,6 @@ public class UpdateConditionAction implements QualityGatesWsAction { | |||
String operator = request.mandatoryParam(PARAM_OPERATOR); | |||
String warning = request.param(PARAM_WARNING); | |||
String error = request.param(PARAM_ERROR); | |||
Integer period = request.paramAsInt(PARAM_PERIOD); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
OrganizationDto organization = wsSupport.getOrganization(dbSession, request); | |||
@@ -90,14 +88,13 @@ public class UpdateConditionAction implements QualityGatesWsAction { | |||
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), period); | |||
emptyToNull(warning), emptyToNull(error)); | |||
UpdateConditionResponse.Builder updateConditionResponse = UpdateConditionResponse.newBuilder() | |||
.setId(updatedCondition.getId()) | |||
.setMetric(updatedCondition.getMetricKey()) | |||
.setOp(updatedCondition.getOperator()); | |||
setNullable(updatedCondition.getWarningThreshold(), updateConditionResponse::setWarning); | |||
setNullable(updatedCondition.getErrorThreshold(), updateConditionResponse::setError); | |||
setNullable(updatedCondition.getPeriod(), updateConditionResponse::setPeriod); | |||
writeProtobuf(updateConditionResponse.build(), request, response); | |||
dbSession.commit(); | |||
} |
@@ -11,7 +11,6 @@ | |||
{ | |||
"id": 3, | |||
"metric": "critical_violations", | |||
"period": 1, | |||
"op": "LT", | |||
"warning": "0" | |||
} |
@@ -101,23 +101,20 @@ public class LiveQualityGateComputerImplTest { | |||
MetricDto metric = db.measures().insertMetric(); | |||
QGateWithOrgDto gate = db.qualityGates().insertQualityGate(organization); | |||
db.qualityGates().setDefaultQualityGate(organization, gate); | |||
QualityGateConditionDto leakCondition = db.qualityGates().addCondition(gate, metric, c -> c.setPeriod(1)); | |||
QualityGateConditionDto absoluteCondition = db.qualityGates().addCondition(gate, metric, c -> c.setPeriod(null)); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(gate, metric); | |||
QualityGate result = underTest.loadQualityGate(db.getSession(), organization, project, branch); | |||
assertThat(result.getId()).isEqualTo("" + gate.getId()); | |||
assertThat(result.getConditions()) | |||
.extracting(Condition::getMetricKey, Condition::getOperator, c -> c.getErrorThreshold().get(), c -> c.getWarningThreshold().get(), Condition::isOnLeakPeriod) | |||
.extracting(Condition::getMetricKey, Condition::getOperator, c -> c.getErrorThreshold().get(), c -> c.getWarningThreshold().get()) | |||
.containsExactlyInAnyOrder( | |||
tuple(metric.getKey(), Condition.Operator.fromDbValue(leakCondition.getOperator()), leakCondition.getErrorThreshold(), leakCondition.getWarningThreshold(), true), | |||
tuple(metric.getKey(), Condition.Operator.fromDbValue(absoluteCondition.getOperator()), absoluteCondition.getErrorThreshold(), absoluteCondition.getWarningThreshold(), | |||
false)); | |||
tuple(metric.getKey(), Condition.Operator.fromDbValue(condition.getOperator()), condition.getErrorThreshold(), condition.getWarningThreshold())); | |||
} | |||
@Test | |||
public void getMetricsRelatedTo() { | |||
Condition condition = new Condition("metric1", Condition.Operator.EQUALS, "10", null, false); | |||
Condition condition = new Condition("metric1", Condition.Operator.EQUALS, "10", null); | |||
QualityGate gate = new QualityGate("1", "foo", ImmutableSet.of(condition)); | |||
Set<String> result = underTest.getMetricsRelatedTo(gate); | |||
@@ -135,7 +132,7 @@ public class LiveQualityGateComputerImplTest { | |||
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, false); | |||
Condition condition = new Condition(conditionMetric.getKey(), Condition.Operator.GREATER_THAN, "10", null); | |||
QualityGate gate = new QualityGate("1", "foo", ImmutableSet.of(condition)); | |||
MeasureMatrix matrix = new MeasureMatrix(singleton(project), asList(conditionMetric, statusMetric, detailsMetric), emptyList()); | |||
@@ -159,13 +156,15 @@ public class LiveQualityGateComputerImplTest { | |||
public void refreshGateStatus_provides_measures_to_evaluator() { | |||
ComponentDto project = ComponentTesting.newPublicProjectDto(newOrganizationDto()); | |||
MetricDto numericMetric = newMetricDto().setValueType(Metric.ValueType.FLOAT.name()); | |||
MetricDto numericNewMetric = newMetricDto().setValueType(Metric.ValueType.FLOAT.name()).setKey("new_metric"); | |||
MetricDto stringMetric = newMetricDto().setValueType(Metric.ValueType.STRING.name()); | |||
MetricDto statusMetric = newMetricDto().setKey(CoreMetrics.ALERT_STATUS_KEY); | |||
MetricDto detailsMetric = newMetricDto().setKey(CoreMetrics.QUALITY_GATE_DETAILS_KEY); | |||
QualityGate gate = new QualityGate("1", "foo", Collections.emptySet()); | |||
LiveMeasureDto numericMeasure = new LiveMeasureDto().setMetricId(numericMetric.getId()).setValue(1.23).setVariation(4.56).setComponentUuid(project.uuid()); | |||
LiveMeasureDto numericNewMeasure = new LiveMeasureDto().setMetricId(numericNewMetric.getId()).setValue(7.8).setVariation(8.9).setComponentUuid(project.uuid()); | |||
LiveMeasureDto stringMeasure = new LiveMeasureDto().setMetricId(stringMetric.getId()).setData("bar").setComponentUuid(project.uuid()); | |||
MeasureMatrix matrix = new MeasureMatrix(singleton(project), asList(statusMetric, detailsMetric, numericMetric, stringMetric), asList(numericMeasure, stringMeasure)); | |||
MeasureMatrix matrix = new MeasureMatrix(singleton(project), asList(statusMetric, detailsMetric, numericMetric, numericNewMetric, stringMetric), asList(numericMeasure, numericNewMeasure, stringMeasure)); | |||
underTest.refreshGateStatus(project, gate, matrix); | |||
@@ -174,14 +173,17 @@ public class LiveQualityGateComputerImplTest { | |||
QualityGateEvaluator.Measure loadedStringMeasure = measures.get(stringMetric.getKey()).get(); | |||
assertThat(loadedStringMeasure.getStringValue()).hasValue("bar"); | |||
assertThat(loadedStringMeasure.getValue()).isEmpty(); | |||
assertThat(loadedStringMeasure.getLeakValue()).isEmpty(); | |||
assertThat(loadedStringMeasure.getType()).isEqualTo(Metric.ValueType.STRING); | |||
QualityGateEvaluator.Measure loadedNumericMeasure = measures.get(numericMetric.getKey()).get(); | |||
assertThat(loadedNumericMeasure.getStringValue()).isEmpty(); | |||
assertThat(loadedNumericMeasure.getValue()).hasValue(1.23); | |||
assertThat(loadedNumericMeasure.getLeakValue()).hasValue(4.56); | |||
assertThat(loadedNumericMeasure.getType()).isEqualTo(Metric.ValueType.FLOAT); | |||
QualityGateEvaluator.Measure loadedNumericNewMeasure = measures.get(numericNewMetric.getKey()).get(); | |||
assertThat(loadedNumericNewMeasure.getStringValue()).isEmpty(); | |||
assertThat(loadedNumericNewMeasure.getNewMetricValue()).hasValue(8.9); | |||
assertThat(loadedNumericNewMeasure.getType()).isEqualTo(Metric.ValueType.FLOAT); | |||
} | |||
private static class TestQualityGateEvaluator implements QualityGateEvaluator { |
@@ -61,23 +61,13 @@ public class QualityGateConditionsUpdaterTest { | |||
private QualityGateConditionsUpdater underTest = new QualityGateConditionsUpdater(db.getDbClient()); | |||
@Test | |||
public void create_warning_condition_without_period() { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "90", null, null); | |||
verifyCondition(result, qualityGate, metric, "LT", "90", null, null); | |||
} | |||
@Test | |||
public void create_error_condition_on_leak_period() { | |||
public void create_error_condition() { | |||
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", 1); | |||
QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", null, "80"); | |||
verifyCondition(result, qualityGate, metric, "LT", null, "80", 1); | |||
verifyCondition(result, qualityGate, metric, "LT", null, "80"); | |||
} | |||
@Test | |||
@@ -89,19 +79,7 @@ public class QualityGateConditionsUpdaterTest { | |||
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, null); | |||
} | |||
@Test | |||
public void fail_to_create_condition_when_condition_on_same_metric_and_on_leak_period_already_exist() { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
db.qualityGates().addCondition(qualityGate, metric, c -> c.setPeriod(1)); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage(format("Condition on metric '%s' over leak period already exists.", metric.getShortName())); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "90", null, 1); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "90", null); | |||
} | |||
@Test | |||
@@ -111,7 +89,7 @@ public class QualityGateConditionsUpdaterTest { | |||
expectedException.expect(NotFoundException.class); | |||
expectedException.expectMessage("There is no metric with key=new_coverage"); | |||
underTest.createCondition(db.getSession(), qualityGate, "new_coverage", "LT", null, "80", 2); | |||
underTest.createCondition(db.getSession(), qualityGate, "new_coverage", "LT", null, "80"); | |||
} | |||
@Test | |||
@@ -123,7 +101,7 @@ public class QualityGateConditionsUpdaterTest { | |||
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", null); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, "80"); | |||
} | |||
@Test | |||
@@ -134,29 +112,7 @@ public class QualityGateConditionsUpdaterTest { | |||
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", 2); | |||
} | |||
@Test | |||
public void fail_to_create_condition_on_missing_period() { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setKey("new_coverage").setValueType(INT.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("A period must be selected for differential metrics."); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, "90", null); | |||
} | |||
@Test | |||
public void fail_to_create_condition_on_invalid_period() { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setKey("new_coverage").setValueType(INT.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("The only valid quality gate period is 1, the leak period."); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, "90", 6); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "UNKNOWN", null, "80"); | |||
} | |||
@Test | |||
@@ -164,20 +120,9 @@ public class QualityGateConditionsUpdaterTest { | |||
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", null); | |||
QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "3"); | |||
verifyCondition(result, qualityGate, metric, "GT", null, "3", null); | |||
} | |||
@Test | |||
public void fail_to_create_condition_on_rating_metric_on_leak_period() { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage(format("The metric '%s' cannot be used on the leak period", metric.getShortName())); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "3", 1); | |||
verifyCondition(result, qualityGate, metric, "GT", null, "3"); | |||
} | |||
@Test | |||
@@ -188,7 +133,7 @@ public class QualityGateConditionsUpdaterTest { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("'6' is not a valid rating"); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "6", null, null); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "6", null); | |||
} | |||
@Test | |||
@@ -199,7 +144,7 @@ public class QualityGateConditionsUpdaterTest { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("'80' is not a valid rating"); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "80", null); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null, "80"); | |||
} | |||
@Test | |||
@@ -210,7 +155,7 @@ public class QualityGateConditionsUpdaterTest { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("There's no worse rating than E (5)"); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "5", null, null); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "5", null); | |||
} | |||
@Test | |||
@@ -219,9 +164,9 @@ public class QualityGateConditionsUpdaterTest { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", value, null, null); | |||
QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", value, null); | |||
verifyCondition(result, qualityGate, metric, "EQ", value, null, null); | |||
verifyCondition(result, qualityGate, metric, "EQ", value, null); | |||
} | |||
@Test | |||
@@ -230,9 +175,9 @@ public class QualityGateConditionsUpdaterTest { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, value, null); | |||
QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, value); | |||
verifyCondition(result, qualityGate, metric, "EQ", null, value, null); | |||
verifyCondition(result, qualityGate, metric, "EQ", null, value); | |||
} | |||
@Test | |||
@@ -244,7 +189,7 @@ public class QualityGateConditionsUpdaterTest { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName())); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", value, null, null); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", value, null); | |||
} | |||
@Test | |||
@@ -256,7 +201,7 @@ public class QualityGateConditionsUpdaterTest { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName())); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, value, null); | |||
underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "EQ", null, value); | |||
} | |||
@Test | |||
@@ -264,23 +209,11 @@ public class QualityGateConditionsUpdaterTest { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60", null, 1); | |||
verifyCondition(result, qualityGate, metric, "GT", "60", null, 1); | |||
} | |||
@Test | |||
public void update_condition_over_leak_period() { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("GT").setWarningThreshold("80").setErrorThreshold(null).setPeriod(1)); | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80")); | |||
QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "LT", null, "80", null); | |||
QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60", null); | |||
verifyCondition(result, qualityGate, metric, "LT", null, "80", null); | |||
verifyCondition(result, qualityGate, metric, "GT", "60", null); | |||
} | |||
@Test | |||
@@ -288,24 +221,11 @@ public class QualityGateConditionsUpdaterTest { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("LT").setWarningThreshold("80").setErrorThreshold(null).setPeriod(1)); | |||
c -> c.setOperator("LT").setWarningThreshold("80").setErrorThreshold(null)); | |||
QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null, null); | |||
QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null); | |||
verifyCondition(result, qualityGate, metric, "GT", "4", null, null); | |||
} | |||
@Test | |||
public void fail_to_update_condition_on_rating_metric_on_leak_period() { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setKey(SQALE_RATING_KEY).setValueType(RATING.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("3").setPeriod(null)); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage(format("The metric '%s' cannot be used on the leak period", metric.getShortName())); | |||
underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null, 1); | |||
verifyCondition(result, qualityGate, metric, "GT", "4", null); | |||
} | |||
@Test | |||
@@ -313,12 +233,12 @@ public class QualityGateConditionsUpdaterTest { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setKey("not_core_rating_metric").setValueType(RATING.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("3").setPeriod(null)); | |||
c -> c.setOperator("LT").setWarningThreshold(null).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, 1); | |||
underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4", null); | |||
} | |||
@Test | |||
@@ -327,28 +247,12 @@ public class QualityGateConditionsUpdaterTest { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setKey(metricKey).setValueType(valueType.name()).setHidden(hidden)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
c -> c.setOperator("LT").setWarningThreshold(null).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, 1); | |||
} | |||
@Test | |||
public void fail_to_update_condition_when_condition_on_same_metric_already_exist() { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto conditionNotOnLeakPeriod = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("GT").setWarningThreshold("80").setErrorThreshold(null).setPeriod(null)); | |||
QualityGateConditionDto conditionOnLeakPeriod = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("GT").setWarningThreshold("80").setErrorThreshold(null).setPeriod(1)); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage(format("Condition on metric '%s' over leak period already exists.", metric.getShortName())); | |||
// Update condition not on leak period to be on leak period => will fail as this condition already exist | |||
underTest.updateCondition(db.getSession(), conditionNotOnLeakPeriod, metric.getKey(), "GT", "80", null, 1); | |||
underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60", null); | |||
} | |||
@Test | |||
@@ -357,11 +261,11 @@ public class QualityGateConditionsUpdaterTest { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80")); | |||
QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value, null, null); | |||
QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value, null); | |||
verifyCondition(result, qualityGate, metric, "EQ", value, null, null); | |||
verifyCondition(result, qualityGate, metric, "EQ", value, null); | |||
} | |||
@Test | |||
@@ -370,11 +274,11 @@ public class QualityGateConditionsUpdaterTest { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80")); | |||
QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", null, value, null); | |||
QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", null, value); | |||
verifyCondition(result, qualityGate, metric, "EQ", null, value, null); | |||
verifyCondition(result, qualityGate, metric, "EQ", null, value); | |||
} | |||
@Test | |||
@@ -383,12 +287,12 @@ public class QualityGateConditionsUpdaterTest { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
c -> c.setOperator("LT").setWarningThreshold(null).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", value, null, null); | |||
underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", value, null); | |||
} | |||
@Test | |||
@@ -397,12 +301,12 @@ public class QualityGateConditionsUpdaterTest { | |||
MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false)); | |||
QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("LT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
c -> c.setOperator("LT").setWarningThreshold(null).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, null); | |||
underTest.updateCondition(db.getSession(), condition, metric.getKey(), "EQ", null, value); | |||
} | |||
@DataProvider | |||
@@ -438,22 +342,19 @@ public class QualityGateConditionsUpdaterTest { | |||
}; | |||
} | |||
private void verifyCondition(QualityGateConditionDto dto, QualityGateDto qualityGate, MetricDto metric, String operator, @Nullable String warning, @Nullable String error, | |||
@Nullable Integer period) { | |||
private void verifyCondition(QualityGateConditionDto dto, QualityGateDto qualityGate, MetricDto metric, String operator, @Nullable String warning, @Nullable 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(reloaded.getPeriod()).isEqualTo(period); | |||
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); | |||
assertThat(dto.getPeriod()).isEqualTo(period); | |||
} | |||
} |
@@ -61,7 +61,6 @@ public class RegisterQualityGatesTest { | |||
@Rule | |||
public LogTester logTester = new LogTester(); | |||
private static final int LEAK_PERIOD = 1; | |||
private static final String BUILT_IN_NAME = "Sonar way"; | |||
private DbClient dbClient = db.getDbClient(); | |||
@@ -108,7 +107,7 @@ public class RegisterQualityGatesTest { | |||
createBuiltInConditions(builtInQualityGate); | |||
// Add another condition | |||
qualityGateConditionsUpdater.createCondition(dbSession, builtInQualityGate, | |||
NEW_SECURITY_REMEDIATION_EFFORT_KEY, OPERATOR_GREATER_THAN, null, "5", LEAK_PERIOD); | |||
NEW_SECURITY_REMEDIATION_EFFORT_KEY, OPERATOR_GREATER_THAN, null, "5"); | |||
dbSession.commit(); | |||
underTest.start(); | |||
@@ -252,28 +251,28 @@ public class RegisterQualityGatesTest { | |||
assertThat(qualityGateDto.isBuiltIn()).isTrue(); | |||
assertThat(gateConditionDao.selectForQualityGate(dbSession, qualityGateDto.getId())) | |||
.extracting(QualityGateConditionDto::getMetricId, QualityGateConditionDto::getOperator, QualityGateConditionDto::getWarningThreshold, | |||
QualityGateConditionDto::getErrorThreshold, QualityGateConditionDto::getPeriod) | |||
QualityGateConditionDto::getErrorThreshold) | |||
.containsOnly( | |||
tuple(newReliability.getId().longValue(), OPERATOR_GREATER_THAN, null, "1", 1), | |||
tuple(newSecurity.getId().longValue(), OPERATOR_GREATER_THAN, null, "1", 1), | |||
tuple(newMaintainability.getId().longValue(), OPERATOR_GREATER_THAN, null, "1", 1), | |||
tuple(newCoverage.getId().longValue(), OPERATOR_LESS_THAN, null, "80", 1), | |||
tuple(newDuplication.getId().longValue(), OPERATOR_GREATER_THAN, null, "3", 1)); | |||
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")); | |||
} | |||
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", LEAK_PERIOD)); | |||
NEW_SECURITY_RATING_KEY, OPERATOR_GREATER_THAN, null, "1")); | |||
conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, | |||
NEW_RELIABILITY_RATING_KEY, OPERATOR_GREATER_THAN, null, "1", LEAK_PERIOD)); | |||
NEW_RELIABILITY_RATING_KEY, OPERATOR_GREATER_THAN, null, "1")); | |||
conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, | |||
NEW_MAINTAINABILITY_RATING_KEY, OPERATOR_GREATER_THAN, null, "1", LEAK_PERIOD)); | |||
NEW_MAINTAINABILITY_RATING_KEY, OPERATOR_GREATER_THAN, null, "1")); | |||
conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, | |||
NEW_COVERAGE_KEY, OPERATOR_LESS_THAN, null, "80", LEAK_PERIOD)); | |||
NEW_COVERAGE_KEY, OPERATOR_LESS_THAN, null, "80")); | |||
conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, | |||
NEW_DUPLICATED_LINES_DENSITY_KEY, OPERATOR_GREATER_THAN, null, "3", LEAK_PERIOD)); | |||
NEW_DUPLICATED_LINES_DENSITY_KEY, OPERATOR_GREATER_THAN, null, "3")); | |||
return conditions; | |||
} |
@@ -109,8 +109,8 @@ public class CopyActionTest { | |||
assertThat(actual.getUuid()).isNotEqualTo(qualityGate.getUuid()); | |||
assertThat(db.getDbClient().gateConditionDao().selectForQualityGate(dbSession, qualityGate.getId())) | |||
.extracting(c-> (int) c.getMetricId(), QualityGateConditionDto::getPeriod, QualityGateConditionDto::getWarningThreshold, QualityGateConditionDto::getErrorThreshold) | |||
.containsExactlyInAnyOrder(tuple(metric.getId(), condition.getPeriod(), condition.getWarningThreshold(), condition.getErrorThreshold())); | |||
.extracting(c-> (int) c.getMetricId(), QualityGateConditionDto::getWarningThreshold, QualityGateConditionDto::getErrorThreshold) | |||
.containsExactlyInAnyOrder(tuple(metric.getId(), condition.getWarningThreshold(), condition.getErrorThreshold())); | |||
} | |||
@Test |
@@ -50,7 +50,6 @@ import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GAT | |||
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_PERIOD; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_WARNING; | |||
public class CreateConditionActionTest { | |||
@@ -120,7 +119,6 @@ public class CreateConditionActionTest { | |||
.setParam(PARAM_METRIC, metric.getKey()) | |||
.setParam(PARAM_OPERATOR, "LT") | |||
.setParam(PARAM_ERROR, "90") | |||
.setParam(PARAM_PERIOD, "1") | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
.execute(); | |||
@@ -216,7 +214,6 @@ public class CreateConditionActionTest { | |||
.setParam(PARAM_OPERATOR, "LT") | |||
.setParam(PARAM_ERROR, "45") | |||
.setParam(PARAM_WARNING, "90") | |||
.setParam(PARAM_PERIOD, "1") | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
.executeProtobuf(CreateConditionResponse.class); | |||
@@ -226,7 +223,6 @@ public class CreateConditionActionTest { | |||
assertThat(response.getOp()).isEqualTo("LT"); | |||
assertThat(response.getWarning()).isEqualTo("90"); | |||
assertThat(response.getError()).isEqualTo("45"); | |||
assertThat(response.getPeriod()).isEqualTo(1); | |||
} | |||
@Test | |||
@@ -260,7 +256,6 @@ public class CreateConditionActionTest { | |||
.containsExactlyInAnyOrder( | |||
tuple("gateId", true), | |||
tuple("metric", true), | |||
tuple("period", false), | |||
tuple("op", false), | |||
tuple("warning", false), | |||
tuple("error", false), | |||
@@ -270,8 +265,8 @@ public class CreateConditionActionTest { | |||
private void assertCondition(QualityGateDto qualityGate, MetricDto metric, String operator, @Nullable String warning, @Nullable String error, @Nullable Integer period) { | |||
assertThat(dbClient.gateConditionDao().selectForQualityGate(dbSession, qualityGate.getId())) | |||
.extracting(QualityGateConditionDto::getQualityGateId, QualityGateConditionDto::getMetricId, QualityGateConditionDto::getOperator, | |||
QualityGateConditionDto::getWarningThreshold, QualityGateConditionDto::getErrorThreshold, QualityGateConditionDto::getPeriod) | |||
.containsExactlyInAnyOrder(tuple(qualityGate.getId(), metric.getId().longValue(), operator, warning, error, period)); | |||
QualityGateConditionDto::getWarningThreshold, QualityGateConditionDto::getErrorThreshold) | |||
.containsExactlyInAnyOrder(tuple(qualityGate.getId(), metric.getId().longValue(), operator, warning, error)); | |||
} | |||
private void logInAsQualityGateAdmin(OrganizationDto organization) { |
@@ -72,9 +72,10 @@ public class ShowActionTest { | |||
OrganizationDto organization = db.organizations().insert(); | |||
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); | |||
db.qualityGates().setDefaultQualityGate(organization, qualityGate); | |||
MetricDto metric = db.measures().insertMetric(); | |||
QualityGateConditionDto condition1 = db.qualityGates().addCondition(qualityGate, metric, c -> c.setOperator("GT").setPeriod(null)); | |||
QualityGateConditionDto condition2 = db.qualityGates().addCondition(qualityGate, metric, c -> c.setOperator("LT").setPeriod(1)); | |||
MetricDto metric1 = db.measures().insertMetric(); | |||
MetricDto metric2 = db.measures().insertMetric(); | |||
QualityGateConditionDto condition1 = db.qualityGates().addCondition(qualityGate, metric1, c -> c.setOperator("GT")); | |||
QualityGateConditionDto condition2 = db.qualityGates().addCondition(qualityGate, metric2, c -> c.setOperator("LT")); | |||
ShowWsResponse response = ws.newRequest() | |||
.setParam("name", qualityGate.getName()) | |||
@@ -86,10 +87,10 @@ public class ShowActionTest { | |||
assertThat(response.getIsBuiltIn()).isFalse(); | |||
assertThat(response.getConditionsList()).hasSize(2); | |||
assertThat(response.getConditionsList()) | |||
.extracting(Condition::getId, Condition::getMetric, Condition::hasPeriod, Condition::getPeriod, Condition::getOp, Condition::getError, Condition::getWarning) | |||
.extracting(Condition::getId, Condition::getMetric, Condition::getOp, Condition::getError, Condition::getWarning) | |||
.containsExactlyInAnyOrder( | |||
tuple(condition1.getId(), metric.getKey(), false, 0, "GT", condition1.getErrorThreshold(), condition1.getWarningThreshold()), | |||
tuple(condition2.getId(), metric.getKey(), true, 1, "LT", condition2.getErrorThreshold(), condition2.getWarningThreshold())); | |||
tuple(condition1.getId(), metric1.getKey(), "GT", condition1.getErrorThreshold(), condition1.getWarningThreshold()), | |||
tuple(condition2.getId(), metric2.getKey(), "LT", condition2.getErrorThreshold(), condition2.getWarningThreshold())); | |||
} | |||
@Test | |||
@@ -397,8 +398,8 @@ public class ShowActionTest { | |||
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").setPeriod(null).setErrorThreshold("0").setWarningThreshold(null)); | |||
db.qualityGates().addCondition(qualityGate, criticalViolationsMetric, c -> c.setOperator("LT").setPeriod(1).setErrorThreshold(null).setWarningThreshold("0")); | |||
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")); | |||
String response = ws.newRequest() | |||
.setParam("name", qualityGate.getName()) |
@@ -51,7 +51,6 @@ 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_ORGANIZATION; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PERIOD; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_WARNING; | |||
public class UpdateConditionActionTest { | |||
@@ -80,7 +79,7 @@ public class UpdateConditionActionTest { | |||
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); | |||
MetricDto metric = insertMetric(); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80")); | |||
ws.newRequest() | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
@@ -90,7 +89,7 @@ public class UpdateConditionActionTest { | |||
.setParam(PARAM_WARNING, "90") | |||
.execute(); | |||
assertCondition(qualityGate, metric, "LT", "90", null, null); | |||
assertCondition(qualityGate, metric, "LT", "90", null); | |||
} | |||
@Test | |||
@@ -100,7 +99,7 @@ public class UpdateConditionActionTest { | |||
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); | |||
MetricDto metric = insertMetric(); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80")); | |||
ws.newRequest() | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
@@ -110,28 +109,7 @@ public class UpdateConditionActionTest { | |||
.setParam(PARAM_ERROR, "90") | |||
.execute(); | |||
assertCondition(qualityGate, metric, "LT", null, "90", null); | |||
} | |||
@Test | |||
public void update_condition_over_leak_period() { | |||
OrganizationDto organization = db.organizations().insert(); | |||
userSession.addPermission(ADMINISTER_QUALITY_GATES, organization); | |||
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); | |||
MetricDto metric = insertMetric(); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
ws.newRequest() | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
.setParam(PARAM_ID, Long.toString(condition.getId())) | |||
.setParam(PARAM_METRIC, metric.getKey()) | |||
.setParam(PARAM_OPERATOR, "LT") | |||
.setParam(PARAM_ERROR, "90") | |||
.setParam(PARAM_PERIOD, "1") | |||
.execute(); | |||
assertCondition(qualityGate, metric, "LT", null, "90", 1); | |||
assertCondition(qualityGate, metric, "LT", null, "90"); | |||
} | |||
@Test | |||
@@ -148,7 +126,7 @@ public class UpdateConditionActionTest { | |||
.setParam(PARAM_WARNING, "90") | |||
.execute(); | |||
assertCondition(qualityGate, metric, "LT", "90", null, null); | |||
assertCondition(qualityGate, metric, "LT", "90", null); | |||
} | |||
@Test | |||
@@ -158,7 +136,7 @@ public class UpdateConditionActionTest { | |||
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); | |||
MetricDto metric = insertMetric(); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80")); | |||
ws.newRequest() | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
@@ -169,7 +147,7 @@ public class UpdateConditionActionTest { | |||
.setParam(PARAM_ERROR, "") | |||
.execute(); | |||
assertCondition(qualityGate, metric, "LT", "90", null, null); | |||
assertCondition(qualityGate, metric, "LT", "90", null); | |||
} | |||
@Test | |||
@@ -179,7 +157,7 @@ public class UpdateConditionActionTest { | |||
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); | |||
MetricDto metric = insertMetric(); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80")); | |||
ws.newRequest() | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
@@ -190,7 +168,7 @@ public class UpdateConditionActionTest { | |||
.setParam(PARAM_WARNING, "") | |||
.execute(); | |||
assertCondition(qualityGate, metric, "LT", null, "90", null); | |||
assertCondition(qualityGate, metric, "LT", null, "90"); | |||
} | |||
@Test | |||
@@ -200,7 +178,7 @@ public class UpdateConditionActionTest { | |||
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); | |||
MetricDto metric = insertMetric(); | |||
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null)); | |||
c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80")); | |||
CreateConditionResponse response = ws.newRequest() | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
@@ -209,7 +187,6 @@ public class UpdateConditionActionTest { | |||
.setParam(PARAM_OPERATOR, "LT") | |||
.setParam(PARAM_WARNING, "90") | |||
.setParam(PARAM_ERROR, "45") | |||
.setParam(PARAM_PERIOD, "1") | |||
.executeProtobuf(CreateConditionResponse.class); | |||
assertThat(response.getId()).isEqualTo(condition.getId()); | |||
@@ -217,7 +194,6 @@ public class UpdateConditionActionTest { | |||
assertThat(response.getOp()).isEqualTo("LT"); | |||
assertThat(response.getWarning()).isEqualTo("90"); | |||
assertThat(response.getError()).isEqualTo("45"); | |||
assertThat(response.getPeriod()).isEqualTo(1); | |||
} | |||
@Test | |||
@@ -313,7 +289,6 @@ public class UpdateConditionActionTest { | |||
.containsExactlyInAnyOrder( | |||
tuple("id", true), | |||
tuple("metric", true), | |||
tuple("period", false), | |||
tuple("op", false), | |||
tuple("warning", false), | |||
tuple("error", false), | |||
@@ -321,15 +296,14 @@ public class UpdateConditionActionTest { | |||
} | |||
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, @Nullable String warning, @Nullable String error) { | |||
assertThat(dbClient.gateConditionDao().selectForQualityGate(dbSession, qualityGate.getId())) | |||
.extracting(QualityGateConditionDto::getQualityGateId, QualityGateConditionDto::getMetricId, QualityGateConditionDto::getOperator, | |||
QualityGateConditionDto::getWarningThreshold, QualityGateConditionDto::getErrorThreshold, QualityGateConditionDto::getPeriod) | |||
.containsExactlyInAnyOrder(tuple(qualityGate.getId(), metric.getId().longValue(), operator, warning, error, period)); | |||
QualityGateConditionDto::getWarningThreshold, QualityGateConditionDto::getErrorThreshold) | |||
.containsExactlyInAnyOrder(tuple(qualityGate.getId(), metric.getId().longValue(), operator, warning, error)); | |||
} | |||
private MetricDto insertMetric() { | |||
return db.measures().insertMetric(m -> m.setValueType(INT.name()).setHidden(false)); | |||
} | |||
} |
@@ -81,7 +81,6 @@ import static java.util.Objects.requireNonNull; | |||
* .setMetricKey("metric key") | |||
* .setOperator(QualityGate.Operator.GREATER_THAN) | |||
* .setErrorThreshold("12") | |||
* .setOnLeakPeriod(true) | |||
* .build(QualityGate.EvaluationStatus.OK, "value")) | |||
* .build()) | |||
* .execute(); | |||
@@ -516,7 +515,6 @@ public class PostProjectAnalysisTaskTester { | |||
private QualityGate.Operator operator; | |||
private String errorThreshold; | |||
private String warningThreshold; | |||
private boolean onLeakPeriod; | |||
private ConditionBuilder() { | |||
// prevents instantiation outside PostProjectAnalysisTaskTester | |||
@@ -542,8 +540,12 @@ public class PostProjectAnalysisTaskTester { | |||
return this; | |||
} | |||
/** | |||
* @deprecated in 7.6. This method has no longer any effect. | |||
* Conditions "on leak period" were removed. Use "New X" conditions instead. | |||
*/ | |||
@Deprecated | |||
public ConditionBuilder setOnLeakPeriod(boolean onLeakPeriod) { | |||
this.onLeakPeriod = onLeakPeriod; | |||
return this; | |||
} | |||
@@ -575,9 +577,13 @@ public class PostProjectAnalysisTaskTester { | |||
return warningThreshold; | |||
} | |||
/** | |||
* @deprecated in 7.6. Conditions "on leak period" were removed. Use "New X" conditions instead. | |||
*/ | |||
@Deprecated | |||
@Override | |||
public boolean isOnLeakPeriod() { | |||
return onLeakPeriod; | |||
return false; | |||
} | |||
@Override | |||
@@ -593,7 +599,6 @@ public class PostProjectAnalysisTaskTester { | |||
", operator=" + operator + | |||
", errorThreshold='" + errorThreshold + '\'' + | |||
", warningThreshold='" + warningThreshold + '\'' + | |||
", onLeakPeriod=" + onLeakPeriod + | |||
'}'; | |||
} | |||
}; | |||
@@ -630,9 +635,13 @@ public class PostProjectAnalysisTaskTester { | |||
return warningThreshold; | |||
} | |||
/** | |||
* @deprecated in 7.6. Conditions "on leak period" were removed. Use "New X" conditions instead. | |||
*/ | |||
@Deprecated | |||
@Override | |||
public boolean isOnLeakPeriod() { | |||
return onLeakPeriod; | |||
return false; | |||
} | |||
@Override | |||
@@ -648,7 +657,6 @@ public class PostProjectAnalysisTaskTester { | |||
", operator=" + operator + | |||
", errorThreshold='" + errorThreshold + '\'' + | |||
", warningThreshold='" + warningThreshold + '\'' + | |||
", onLeakPeriod=" + onLeakPeriod + | |||
", value='" + value + '\'' + | |||
'}'; | |||
} |
@@ -100,8 +100,11 @@ public interface QualityGate { | |||
String getWarningThreshold(); | |||
/** | |||
* Whether this condition is defined on the leak period or on an absolute value | |||
* Whether this condition is defined on the leak period or on an absolute value. | |||
* @deprecated in 7.6. Implementations should always return false. | |||
* Conditions "on leak period" were removed. Use "New X" conditions instead. | |||
*/ | |||
@Deprecated | |||
boolean isOnLeakPeriod(); | |||
/** |
@@ -130,7 +130,7 @@ public class ConditionBuilder_PostProjectAnalysisTaskTesterTest { | |||
assertThat(underTest.buildNoValue().toString()) | |||
.isEqualTo( | |||
"Condition{status=NO_VALUE, metricKey='some metric key', operator=GREATER_THAN, " + | |||
"errorThreshold='some error threshold', warningThreshold='some warning threshold', onLeakPeriod=false}"); | |||
"errorThreshold='some error threshold', warningThreshold='some warning threshold'}"); | |||
} | |||
@Test | |||
@@ -143,7 +143,6 @@ public class ConditionBuilder_PostProjectAnalysisTaskTesterTest { | |||
assertThat(condition.getOperator()).isEqualTo(SOME_OPERATOR); | |||
assertThat(condition.getErrorThreshold()).isEqualTo(SOME_ERROR_THRESHOLD); | |||
assertThat(condition.getWarningThreshold()).isEqualTo(SOME_WARNING_THRESHOLD); | |||
assertThat(condition.isOnLeakPeriod()).isTrue(); | |||
} | |||
@Test | |||
@@ -234,7 +233,7 @@ public class ConditionBuilder_PostProjectAnalysisTaskTesterTest { | |||
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', onLeakPeriod=false, value='some value'}"); | |||
+ "errorThreshold='some error threshold', warningThreshold='some warning threshold', value='some value'}"); | |||
} | |||
@Test | |||
@@ -266,31 +265,9 @@ public class ConditionBuilder_PostProjectAnalysisTaskTesterTest { | |||
assertThat(condition.getOperator()).isEqualTo(SOME_OPERATOR); | |||
assertThat(condition.getErrorThreshold()).isEqualTo(SOME_ERROR_THRESHOLD); | |||
assertThat(condition.getWarningThreshold()).isEqualTo(SOME_WARNING_THRESHOLD); | |||
assertThat(condition.isOnLeakPeriod()).isTrue(); | |||
assertThat(condition.getValue()).isEqualTo(SOME_VALUE); | |||
} | |||
@Test | |||
public void isOnLeakPeriod_is_false_by_default() { | |||
initValidBuilder(); | |||
assertThat(underTest.buildNoValue().isOnLeakPeriod()).isFalse(); | |||
assertThat(underTest.build(SOME_STATUS_BUT_NO_VALUE, SOME_VALUE).isOnLeakPeriod()).isFalse(); | |||
} | |||
@Test | |||
public void isOnLeakPeriod_changes_isOnLeakPeriod_returned_value() { | |||
initValidBuilder().setOnLeakPeriod(true); | |||
assertThat(underTest.buildNoValue().isOnLeakPeriod()).isTrue(); | |||
assertThat(underTest.build(SOME_STATUS_BUT_NO_VALUE, SOME_VALUE).isOnLeakPeriod()).isTrue(); | |||
initValidBuilder().setOnLeakPeriod(false); | |||
assertThat(underTest.buildNoValue().isOnLeakPeriod()).isFalse(); | |||
assertThat(underTest.build(SOME_STATUS_BUT_NO_VALUE, SOME_VALUE).isOnLeakPeriod()).isFalse(); | |||
} | |||
private PostProjectAnalysisTaskTester.ConditionBuilder initValidBuilder() { | |||
underTest.setMetricKey(SOME_METRIC_KEY).setOperator(SOME_OPERATOR).setErrorThreshold(SOME_ERROR_THRESHOLD).setWarningThreshold(SOME_WARNING_THRESHOLD); | |||
return underTest; |
@@ -36,7 +36,6 @@ public class CreateConditionRequest { | |||
private String metric; | |||
private String op; | |||
private String organization; | |||
private String period; | |||
private String warning; | |||
/** | |||
@@ -108,21 +107,6 @@ public class CreateConditionRequest { | |||
return organization; | |||
} | |||
/** | |||
* Possible values: | |||
* <ul> | |||
* <li>"1"</li> | |||
* </ul> | |||
*/ | |||
public CreateConditionRequest setPeriod(String period) { | |||
this.period = period; | |||
return this; | |||
} | |||
public String getPeriod() { | |||
return period; | |||
} | |||
/** | |||
* Example value: "5" | |||
*/ |
@@ -92,7 +92,6 @@ public class QualitygatesService extends BaseService { | |||
.setParam("metric", request.getMetric()) | |||
.setParam("op", request.getOp()) | |||
.setParam("organization", request.getOrganization()) | |||
.setParam("period", request.getPeriod()) | |||
.setParam("warning", request.getWarning()), | |||
CreateConditionResponse.parser()); | |||
} | |||
@@ -308,7 +307,6 @@ public class QualitygatesService extends BaseService { | |||
.setParam("metric", request.getMetric()) | |||
.setParam("op", request.getOp()) | |||
.setParam("organization", request.getOrganization()) | |||
.setParam("period", request.getPeriod()) | |||
.setParam("warning", request.getWarning()), | |||
UpdateConditionResponse.parser()); | |||
} |
@@ -36,7 +36,6 @@ public class UpdateConditionRequest { | |||
private String metric; | |||
private String op; | |||
private String organization; | |||
private String period; | |||
private String warning; | |||
/** | |||
@@ -108,21 +107,6 @@ public class UpdateConditionRequest { | |||
return organization; | |||
} | |||
/** | |||
* Possible values: | |||
* <ul> | |||
* <li>"1"</li> | |||
* </ul> | |||
*/ | |||
public UpdateConditionRequest setPeriod(String period) { | |||
this.period = period; | |||
return this; | |||
} | |||
public String getPeriod() { | |||
return period; | |||
} | |||
/** | |||
* Example value: "5" | |||
*/ |
@@ -105,7 +105,6 @@ message CreateConditionResponse { | |||
optional string op = 3; | |||
optional string warning = 4; | |||
optional string error = 5; | |||
optional int32 period = 6; | |||
} | |||
// POST api/qualitygates/update_condition | |||
@@ -115,7 +114,6 @@ message UpdateConditionResponse { | |||
optional string op = 3; | |||
optional string warning = 4; | |||
optional string error = 5; | |||
optional int32 period = 6; | |||
} | |||
// GET api/qualitygates/show | |||
@@ -129,7 +127,6 @@ message ShowWsResponse { | |||
message Condition { | |||
optional int64 id = 1; | |||
optional string metric = 2; | |||
optional int32 period = 3; | |||
optional string op = 4; | |||
optional string warning = 5; | |||
optional string error = 6; |