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;
}
private String errorThreshold;
@CheckForNull
private String warningThreshold;
- private boolean onLeakPeriod;
@CheckForNull
private String value;
private QualityGate.EvaluationStatus status;
return this;
}
+ /**
+ * @deprecated in 7.6. This method has no longer any effect.
+ */
+ @Deprecated
public Builder setOnLeakPeriod(boolean onLeakPeriod) {
- this.onLeakPeriod = onLeakPeriod;
return this;
}
return warningThreshold;
}
+ /**
+ * @deprecated in 7.6. Conditions "on leak period" were removed. Use "New X" conditions instead.
+ */
+ @Deprecated
@Override
public boolean isOnLeakPeriod() {
return onLeakPeriod;
", operator=" + operator +
", errorThreshold='" + errorThreshold + '\'' +
", warningThreshold='" + warningThreshold + '\'' +
- ", onLeakPeriod=" + onLeakPeriod +
", value='" + value + '\'' +
'}';
}
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;
.setOperator(convert(input.getOperator()))
.setErrorThreshold(input.getErrorThreshold())
.setWarningThreshold(input.getWarningThreshold())
- .setOnLeakPeriod(input.hasPeriod())
.setValue(conditionStatus.getValue())
.build();
}
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;
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) {
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;
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;
}
return metric;
}
- public boolean hasPeriod() {
- return hasPeriod;
+ public boolean useVariation() {
+ return useVariation;
}
public Operator getOperator() {
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)
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;
@CheckForNull
private static Comparable parseMeasure(Condition condition, Measure measure) {
- if (condition.hasPeriod()) {
+ if (condition.useVariation()) {
return parseMeasureFromVariation(condition, measure);
}
switch (measure.getValueType()) {
@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);
+ }
}
-
}
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, "!=",
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
}
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();
}
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;
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()));
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())));
}
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;
* 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;
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);
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());
.setOperator(QualityGate.Operator.GREATER_THAN)
.setErrorThreshold(ERROR_THRESHOLD)
.setWarningThreshold(WARN_THRESHOLD)
- .setOnLeakPeriod(true)
.setValue(VALUE);
@Test
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
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
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);
}
}
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();
@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));
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");
}
}
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";
@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),
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
- " \"period\":1," +
" \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
- " \"period\":1," +
" \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
- " \"period\":1," +
" \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
*/
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;
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();
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
}
@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);
+ }
}
*/
package org.sonar.ce.task.projectanalysis.qualitygate;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
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
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
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);
}
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}");
}
-
}
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;
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;
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() {
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));
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:
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");
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
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
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);
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) {
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);
.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()
}
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) {
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);
}
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()))
private String metricKey;
- private Integer period;
-
private String operator;
private String warningThreshold;
return this;
}
- @CheckForNull
- public Integer getPeriod() {
- return period;
- }
-
- public QualityGateConditionDto setPeriod(@Nullable Integer period) {
- this.period = period;
- return this;
- }
-
public String getOperator() {
return operator;
}
<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>
operator=#{operator},
value_warning=#{warningThreshold},
value_error=#{errorThreshold},
- period=#{period},
updated_at=#{updatedAt}
where id=#{id}
</update>
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
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();
}
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");
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);
<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>
<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>
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);
}
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);
@Override
public int hashCode() {
- return Objects.hash(metricKey, operator, warningThreshold, errorThreshold, onLeakPeriod);
+ return Objects.hash(metricKey, operator, warningThreshold, errorThreshold);
}
@Override
", operator=" + operator +
", warningThreshold=" + toString(warningThreshold) +
", errorThreshold=" + toString(errorThreshold) +
- ", onLeakPeriod=" + onLeakPeriod +
'}';
}
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());
Optional<String> getStringValue();
- OptionalDouble getLeakValue();
+ OptionalDouble getNewMetricValue();
}
}
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 {
.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)));
} else {
result.addCondition(evaluation);
}
- }
+ });
result.setStatus(overallStatusOf(result.getEvaluatedConditions()));
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;
}
}
return Level.OK;
}
-
}
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
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() {
public String getWarnThreshold() {
return null;
}
-
- public boolean isOnLeak() {
- return onLeak;
- }
}
}
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();
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));
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));
}
@Override
- public OptionalDouble getLeakValue() {
+ public OptionalDouble getNewMetricValue() {
return leakValue == null ? OptionalDouble.empty() : OptionalDouble.of(leakValue);
}
}
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
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();
}
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
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
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());
}
}
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();
@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'}");
}
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}");
}
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"));
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());
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
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
--- /dev/null
+/*
+ * 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);
+ }
+}
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();
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());
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'}" +
"]}");
}
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
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());
}
}
@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));
}
}
@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)
" \"operator\": \"GREATER_THAN\"," +
" \"value\": \"74.0\"," +
" \"status\": \"WARN\"," +
- " \"onLeakPeriod\": true," +
" \"errorThreshold\": \"70.0\"," +
" \"warningThreshold\": \"75.0\"" +
" }" +
public void create_payload_with_gate_conditions_without_value() {
CeTask task = new CeTask("#1", CeTask.Status.SUCCESS);
- Condition condition = new Condition("coverage", Condition.Operator.GREATER_THAN, "70.0", "75.0", 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)
" \"metric\": \"coverage\"," +
" \"operator\": \"GREATER_THAN\"," +
" \"status\": \"NO_VALUE\"," +
- " \"onLeakPeriod\": false," +
" \"errorThreshold\": \"70.0\"," +
" \"warningThreshold\": \"75.0\"" +
" }" +
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;
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);
}
@Override
- public OptionalDouble getLeakValue() {
+ public OptionalDouble getNewMetricValue() {
if (dto.getVariation() == null) {
return OptionalDouble.empty();
}
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;
}
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;
}
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);
}
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) {
}
}
- 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;
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));
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);
}
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;
// 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);
private static class QualityGateCondition {
private Long id;
private String metricKey;
- private Integer period;
private String operator;
private String warningThreshold;
private String errorThreshold;
.setId(qualityGateConditionDto.getId())
.setMetricKey(mapping.get(qualityGateConditionDto.getMetricId()))
.setOperator(qualityGateConditionDto.getOperator())
- .setPeriod(qualityGateConditionDto.getPeriod())
.setErrorThreshold(qualityGateConditionDto.getErrorThreshold())
.setWarningThreshold(qualityGateConditionDto.getWarningThreshold());
}
return this;
}
- public Integer getPeriod() {
- return period;
- }
-
- public QualityGateCondition setPeriod(Integer period) {
- this.period = period;
- return this;
- }
-
public String getOperator() {
return operator;
}
.setId(id)
.setMetricKey(metricKey)
.setOperator(operator)
- .setPeriod(period)
.setErrorThreshold(errorThreshold)
.setWarningThreshold(warningThreshold)
.setQualityGateId(qualityGateId);
}
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);
// 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);
}
}
}
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;
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();
}
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 {
.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")
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";
.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();
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;
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);
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();
}
{
"id": 3,
"metric": "critical_violations",
- "period": 1,
"op": "LT",
"warning": "0"
}
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);
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());
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);
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 {
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
};
}
- 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);
}
}
@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();
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();
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;
}
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
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 {
.setParam(PARAM_METRIC, metric.getKey())
.setParam(PARAM_OPERATOR, "LT")
.setParam(PARAM_ERROR, "90")
- .setParam(PARAM_PERIOD, "1")
.setParam(PARAM_ORGANIZATION, organization.getKey())
.execute();
.setParam(PARAM_OPERATOR, "LT")
.setParam(PARAM_ERROR, "45")
.setParam(PARAM_WARNING, "90")
- .setParam(PARAM_PERIOD, "1")
.setParam(PARAM_ORGANIZATION, organization.getKey())
.executeProtobuf(CreateConditionResponse.class);
assertThat(response.getOp()).isEqualTo("LT");
assertThat(response.getWarning()).isEqualTo("90");
assertThat(response.getError()).isEqualTo("45");
- assertThat(response.getPeriod()).isEqualTo(1);
}
@Test
.containsExactlyInAnyOrder(
tuple("gateId", true),
tuple("metric", true),
- tuple("period", false),
tuple("op", false),
tuple("warning", false),
tuple("error", false),
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) {
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())
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
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())
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 {
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())
.setParam(PARAM_WARNING, "90")
.execute();
- assertCondition(qualityGate, metric, "LT", "90", null, null);
+ assertCondition(qualityGate, metric, "LT", "90", null);
}
@Test
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
MetricDto metric = insertMetric();
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
- c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
+ c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80"));
ws.newRequest()
.setParam(PARAM_ORGANIZATION, organization.getKey())
.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
.setParam(PARAM_WARNING, "90")
.execute();
- assertCondition(qualityGate, metric, "LT", "90", null, null);
+ assertCondition(qualityGate, metric, "LT", "90", null);
}
@Test
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
MetricDto metric = insertMetric();
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
- c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
+ c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80"));
ws.newRequest()
.setParam(PARAM_ORGANIZATION, organization.getKey())
.setParam(PARAM_ERROR, "")
.execute();
- assertCondition(qualityGate, metric, "LT", "90", null, null);
+ assertCondition(qualityGate, metric, "LT", "90", null);
}
@Test
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
MetricDto metric = insertMetric();
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
- c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
+ c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80"));
ws.newRequest()
.setParam(PARAM_ORGANIZATION, organization.getKey())
.setParam(PARAM_WARNING, "")
.execute();
- assertCondition(qualityGate, metric, "LT", null, "90", null);
+ assertCondition(qualityGate, metric, "LT", null, "90");
}
@Test
QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
MetricDto metric = insertMetric();
QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric,
- c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80").setPeriod(null));
+ c -> c.setOperator("GT").setWarningThreshold(null).setErrorThreshold("80"));
CreateConditionResponse response = ws.newRequest()
.setParam(PARAM_ORGANIZATION, organization.getKey())
.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());
assertThat(response.getOp()).isEqualTo("LT");
assertThat(response.getWarning()).isEqualTo("90");
assertThat(response.getError()).isEqualTo("45");
- assertThat(response.getPeriod()).isEqualTo(1);
}
@Test
.containsExactlyInAnyOrder(
tuple("id", true),
tuple("metric", true),
- tuple("period", false),
tuple("op", false),
tuple("warning", false),
tuple("error", false),
}
- private void assertCondition(QualityGateDto qualityGate, MetricDto metric, String operator, @Nullable String warning, @Nullable String error, @Nullable Integer period) {
+ private void assertCondition(QualityGateDto qualityGate, MetricDto metric, String operator, @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));
}
-
}
* .setMetricKey("metric key")
* .setOperator(QualityGate.Operator.GREATER_THAN)
* .setErrorThreshold("12")
- * .setOnLeakPeriod(true)
* .build(QualityGate.EvaluationStatus.OK, "value"))
* .build())
* .execute();
private QualityGate.Operator operator;
private String errorThreshold;
private String warningThreshold;
- private boolean onLeakPeriod;
private ConditionBuilder() {
// prevents instantiation outside 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;
}
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
", operator=" + operator +
", errorThreshold='" + errorThreshold + '\'' +
", warningThreshold='" + warningThreshold + '\'' +
- ", onLeakPeriod=" + onLeakPeriod +
'}';
}
};
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
", operator=" + operator +
", errorThreshold='" + errorThreshold + '\'' +
", warningThreshold='" + warningThreshold + '\'' +
- ", onLeakPeriod=" + onLeakPeriod +
", value='" + value + '\'' +
'}';
}
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();
/**
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
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
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
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;
private String metric;
private String op;
private String organization;
- private String period;
private String warning;
/**
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"
*/
.setParam("metric", request.getMetric())
.setParam("op", request.getOp())
.setParam("organization", request.getOrganization())
- .setParam("period", request.getPeriod())
.setParam("warning", request.getWarning()),
CreateConditionResponse.parser());
}
.setParam("metric", request.getMetric())
.setParam("op", request.getOp())
.setParam("organization", request.getOrganization())
- .setParam("period", request.getPeriod())
.setParam("warning", request.getWarning()),
UpdateConditionResponse.parser());
}
private String metric;
private String op;
private String organization;
- private String period;
private String warning;
/**
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"
*/
optional string op = 3;
optional string warning = 4;
optional string error = 5;
- optional int32 period = 6;
}
// POST api/qualitygates/update_condition
optional string op = 3;
optional string warning = 4;
optional string error = 5;
- optional int32 period = 6;
}
// GET api/qualitygates/show
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;