Browse Source

SONAR-8743 Handle only leak period when computing quality gate measure

tags/6.3-RC1
Julien Lancelot 7 years ago
parent
commit
d64f1a2a35
18 changed files with 117 additions and 178 deletions
  1. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/api/posttask/ConditionToCondition.java
  2. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/measure/qualitygatedetails/QualityGateDetailsData.java
  3. 8
    10
      server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitygate/Condition.java
  4. 4
    25
      server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitygate/ConditionEvaluator.java
  5. 4
    4
      server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitygate/EvaluationResultTextConverterImpl.java
  6. 1
    1
      server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitygate/QualityGateServiceImpl.java
  7. 4
    22
      server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/QualityGateMeasuresStep.java
  8. 6
    7
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/api/posttask/ConditionToConditionTest.java
  9. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java
  10. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/qualitygatedetails/EvaluatedConditionTest.java
  11. 38
    39
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/qualitygatedetails/QualityGateDetailsDataTest.java
  12. 14
    31
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/ConditionEvaluatorTest.java
  13. 7
    8
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/ConditionTest.java
  14. 7
    7
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/EvaluationResultTextConverterTest.java
  15. 4
    4
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/QualityGateServiceImplTest.java
  16. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/QualityGateEventsStepTest.java
  17. 12
    12
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/QualityGateMeasuresStepTest.java
  18. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputeMeasureVariationsStepTest.java

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/api/posttask/ConditionToCondition.java View File

@@ -43,7 +43,7 @@ class ConditionToCondition implements Function<Condition, QualityGate.Condition>

@Override
@Nonnull
public QualityGate.Condition apply(@Nonnull Condition input) {
public QualityGate.Condition apply(Condition input) {
String metricKey = input.getMetric().getKey();
ConditionStatus conditionStatus = statusPerConditions.get(input);
checkState(conditionStatus != null, "Missing ConditionStatus for condition on metric key %s", metricKey);
@@ -53,7 +53,7 @@ class ConditionToCondition implements Function<Condition, QualityGate.Condition>
.setOperator(convert(input.getOperator()))
.setErrorThreshold(input.getErrorThreshold())
.setWarningThreshold(input.getWarningThreshold())
.setOnLeakPeriod(input.getPeriod() != null)
.setOnLeakPeriod(input.hasPeriod())
.setValue(conditionStatus.getValue())
.build();
}

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/measure/qualitygatedetails/QualityGateDetailsData.java View File

@@ -58,8 +58,8 @@ public class QualityGateDetailsData {
JsonObject result = new JsonObject();
result.addProperty("metric", condition.getMetric().getKey());
result.addProperty("op", condition.getOperator().getDbValue());
if (condition.getPeriod() != null) {
result.addProperty("period", condition.getPeriod());
if (condition.hasPeriod()) {
result.addProperty("period", 1);
}
if (condition.getWarningThreshold() != null) {
result.addProperty("warning", condition.getWarningThreshold());

+ 8
- 10
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitygate/Condition.java View File

@@ -51,15 +51,14 @@ public class Condition {
private final String warningThreshold;
@CheckForNull
private final String errorThreshold;
@CheckForNull
private final Integer period;
private final boolean hasPeriod;

public Condition(Metric metric, String operator,
@Nullable String errorThreshold, @Nullable String warningThreshold,
@Nullable Integer period) {
boolean hasPeriod) {
this.metric = requireNonNull(metric);
this.operator = parseFromDbValue(requireNonNull(operator));
this.period = period;
this.hasPeriod = hasPeriod;
this.errorThreshold = errorThreshold;
this.warningThreshold = warningThreshold;
}
@@ -77,9 +76,8 @@ public class Condition {
return metric;
}

@CheckForNull
public Integer getPeriod() {
return period;
public boolean hasPeriod() {
return hasPeriod;
}

public Operator getOperator() {
@@ -106,19 +104,19 @@ public class Condition {
}
Condition that = (Condition) o;
return java.util.Objects.equals(metric, that.metric)
&& java.util.Objects.equals(period, that.period);
&& java.util.Objects.equals(hasPeriod, that.hasPeriod);
}

@Override
public int hashCode() {
return hash(metric, period);
return hash(metric, hasPeriod);
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("metric", metric)
.add("period", period)
.add("hasPeriod", hasPeriod)
.add("operator", operator)
.add("warningThreshold", warningThreshold)
.add("errorThreshold", errorThreshold)

+ 4
- 25
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitygate/ConditionEvaluator.java View File

@@ -23,7 +23,6 @@ import java.util.Optional;
import javax.annotation.CheckForNull;
import org.apache.commons.lang.StringUtils;
import org.sonar.server.computation.task.projectanalysis.measure.Measure;
import org.sonar.server.computation.task.projectanalysis.measure.MeasureVariations;
import org.sonar.server.computation.task.projectanalysis.metric.Metric;

import static com.google.common.base.Preconditions.checkArgument;
@@ -31,8 +30,6 @@ import static java.util.Optional.of;

public final class ConditionEvaluator {

private static final Optional<Double> NO_PERIOD_VALUE = Optional.empty();

/**
* Evaluates the condition for the specified measure
*/
@@ -118,7 +115,7 @@ public final class ConditionEvaluator {

@CheckForNull
private static Comparable parseMeasure(Condition condition, Measure measure) {
if (condition.getPeriod() != null) {
if (condition.hasPeriod()) {
return parseMeasureFromVariation(condition, measure);
}
switch (measure.getValueType()) {
@@ -144,7 +141,7 @@ public final class ConditionEvaluator {

@CheckForNull
private static Comparable parseMeasureFromVariation(Condition condition, Measure measure) {
Optional<Double> periodValue = getPeriodValue(measure, condition.getPeriod());
Optional<Double> periodValue = getPeriodValue(measure);
if (periodValue.isPresent()) {
switch (condition.getMetric().getType().getValueType()) {
case BOOLEAN:
@@ -165,26 +162,8 @@ public final class ConditionEvaluator {
return null;
}

private static Optional<Double> getPeriodValue(Measure measure, int period) {
if (!measure.hasVariations()) {
return Optional.empty();
}

MeasureVariations variations = measure.getVariations();
switch (period) {
case 1:
return variations.hasVariation1() ? of(variations.getVariation1()) : NO_PERIOD_VALUE;
case 2:
return variations.hasVariation2() ? of(variations.getVariation2()) : NO_PERIOD_VALUE;
case 3:
return variations.hasVariation3() ? of(variations.getVariation3()) : NO_PERIOD_VALUE;
case 4:
return variations.hasVariation4() ? of(variations.getVariation4()) : NO_PERIOD_VALUE;
case 5:
return variations.hasVariation5() ? of(variations.getVariation5()) : NO_PERIOD_VALUE;
default:
throw new IllegalArgumentException("Following index period is not allowed : " + period);
}
private static Optional<Double> getPeriodValue(Measure measure) {
return measure.hasVariation() ? Optional.of(measure.getVariation()) : Optional.empty();
}

}

+ 4
- 4
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitygate/EvaluationResultTextConverterImpl.java View File

@@ -68,13 +68,13 @@ public final class EvaluationResultTextConverterImpl implements EvaluationResult
}

private String getAlertLabel(Condition condition, Measure.Level level) {
Integer alertPeriod = condition.getPeriod();
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 (alertPeriod != null && !condition.getMetric().getKey().startsWith(VARIATION_METRIC_PREFIX)) {
if (hasPeriod && !condition.getMetric().getKey().startsWith(VARIATION_METRIC_PREFIX)) {
String variation = i18n.message(Locale.ENGLISH, VARIATION, VARIATION).toLowerCase(Locale.ENGLISH);
stringBuilder.append(" ").append(variation);
}
@@ -83,8 +83,8 @@ public final class EvaluationResultTextConverterImpl implements EvaluationResult
.append(" ").append(OPERATOR_LABELS.get(condition.getOperator())).append(" ")
.append(alertValue(condition, level));

if (alertPeriod != null) {
Period period = periodsHolder.getPeriod(alertPeriod);
if (hasPeriod) {
Period period = periodsHolder.getPeriod();
stringBuilder.append(" ").append(periods.label(period.getMode(), period.getModeParameter(), DateUtils.longToDate(period.getSnapshotDate())));
}


+ 1
- 1
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitygate/QualityGateServiceImpl.java View File

@@ -40,7 +40,7 @@ public class QualityGateServiceImpl implements QualityGateService {
this.conditionDao = conditionDao;
this.conditionDtoToBean = (QualityGateConditionDto input) -> {
Metric metric = metricRepository.getById(input.getMetricId());
return new Condition(metric, input.getOperator(), input.getErrorThreshold(), input.getWarningThreshold(), input.getPeriod());
return new Condition(metric, input.getOperator(), input.getErrorThreshold(), input.getWarningThreshold(), input.getPeriod() != null);
};
}


+ 4
- 22
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/QualityGateMeasuresStep.java View File

@@ -33,6 +33,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.core.util.stream.Collectors;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit;
import org.sonar.server.computation.task.projectanalysis.component.DepthTraversalTypeAwareCrawler;
@@ -73,8 +74,8 @@ import static org.sonar.server.computation.task.projectanalysis.qualitygate.Cond
* It must be executed after the computation of differential measures {@link ComputeMeasureVariationsStep}
*/
public class QualityGateMeasuresStep implements ComputationStep {
private static final Ordering<Condition> PERIOD_ORDERING = Ordering.natural().nullsLast()
.onResultOf(ConditionToPeriod.INSTANCE);
// 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;
@@ -170,7 +171,7 @@ public class QualityGateMeasuresStep implements ComputationStep {
}

private void updateMeasures(Component project, Set<Condition> conditions, QualityGateDetailsDataBuilder builder) {
Multimap<Metric, Condition> conditionsPerMetric = from(conditions).index(ConditionToMetric.INSTANCE);
Multimap<Metric, Condition> conditionsPerMetric = conditions.stream().collect(Collectors.index(Condition::getMetric, java.util.function.Function.identity()));
for (Map.Entry<Metric, Collection<Condition>> entry : conditionsPerMetric.asMap().entrySet()) {
Metric metric = entry.getKey();
Optional<Measure> measure = measureRepository.getRawMeasure(project, metric);
@@ -277,23 +278,4 @@ public class QualityGateMeasuresStep implements ComputationStep {
}
}

private enum ConditionToMetric implements Function<Condition, Metric> {
INSTANCE;

@Override
@Nonnull
public Metric apply(@Nonnull Condition input) {
return input.getMetric();
}
}

public enum ConditionToPeriod implements Function<Condition, Integer> {
INSTANCE;

@Override
@Nullable
public Integer apply(@Nonnull Condition input) {
return input.getPeriod();
}
}
}

+ 6
- 7
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/api/posttask/ConditionToConditionTest.java View File

@@ -46,7 +46,7 @@ public class ConditionToConditionTest {
private static final Map<Condition, ConditionStatus> NO_STATUS_PER_CONDITIONS = Collections.emptyMap();
private static final String SOME_VALUE = "some value";
private static final ConditionStatus SOME_CONDITION_STATUS = ConditionStatus.create(ConditionStatus.EvaluationStatus.OK, SOME_VALUE);
private static final Condition SOME_CONDITION = new Condition(newMetric(METRIC_KEY), Condition.Operator.EQUALS.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD, 1);
private static final Condition SOME_CONDITION = new Condition(newMetric(METRIC_KEY), Condition.Operator.EQUALS.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD, true);

@Rule
public ExpectedException expectedException = ExpectedException.none();
@@ -98,7 +98,7 @@ public class ConditionToConditionTest {
@Test
@UseDataProvider("allOperatorValues")
public void apply_converts_all_values_of_operator(Condition.Operator operator) {
Condition condition = new Condition(newMetric(METRIC_KEY), operator.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD, 1);
Condition condition = new Condition(newMetric(METRIC_KEY), operator.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD, true);
ConditionToCondition underTest = new ConditionToCondition(of(condition, SOME_CONDITION_STATUS));

assertThat(underTest.apply(condition).getOperator().name()).isEqualTo(operator.name());
@@ -106,7 +106,7 @@ public class ConditionToConditionTest {

@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, null);
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));
@@ -117,11 +117,10 @@ public class ConditionToConditionTest {

@Test
public void apply_copies_value() {
Condition otherCondition = new Condition(newMetric(METRIC_KEY), Condition.Operator.NOT_EQUALS.getDbValue(), ERROR_THRESHOLD, WARN_THRESHOLD, null);
Condition otherCondition = 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,
otherCondition, ConditionStatus.NO_VALUE_STATUS
));
SOME_CONDITION, SOME_CONDITION_STATUS,
otherCondition, ConditionStatus.NO_VALUE_STATUS));

assertThat(underTest.apply(SOME_CONDITION).getValue()).isEqualTo(SOME_VALUE);


+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java View File

@@ -271,7 +271,7 @@ public class PostProjectAnalysisTasksExecutorTest {
private static Condition createCondition(String metricKey) {
Metric metric = mock(Metric.class);
when(metric.getKey()).thenReturn(metricKey);
return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), "error threshold", "warn threshold", null);
return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), "error threshold", "warn threshold", false);
}

}

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/qualitygatedetails/EvaluatedConditionTest.java View File

@@ -29,7 +29,7 @@ import static org.mockito.Mockito.mock;

public class EvaluatedConditionTest {

private static final Condition SOME_CONDITION = new Condition(mock(Metric.class), Condition.Operator.EQUALS.getDbValue(), "1", null, null);
private static final Condition SOME_CONDITION = new Condition(mock(Metric.class), Condition.Operator.EQUALS.getDbValue(), "1", null, false);
private static final Measure.Level SOME_LEVEL = Measure.Level.OK;
private static final String SOME_VALUE = "some value";


+ 38
- 39
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/qualitygatedetails/QualityGateDetailsDataTest.java View File

@@ -44,53 +44,52 @@ public class QualityGateDetailsDataTest {
String actualJson = new QualityGateDetailsData(Measure.Level.OK, Collections.<EvaluatedCondition>emptyList()).toJson();

JsonAssert.assertJson(actualJson).isSimilarTo("{" +
"\"level\":\"OK\"," +
"\"conditions\":[]" +
"}");
"\"level\":\"OK\"," +
"\"conditions\":[]" +
"}");
}

@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", 10);
Condition condition = new Condition(new MetricImpl(1, "key1", "name1", Metric.MetricType.STRING), Condition.Operator.GREATER_THAN.getDbValue(), "errorTh", "warnTh", true);
ImmutableList<EvaluatedCondition> evaluatedConditions = ImmutableList.of(
new EvaluatedCondition(condition, Measure.Level.OK, value),
new EvaluatedCondition(condition, Measure.Level.WARN, value),
new EvaluatedCondition(condition, Measure.Level.ERROR, value)
);
new EvaluatedCondition(condition, Measure.Level.OK, value),
new EvaluatedCondition(condition, Measure.Level.WARN, value),
new EvaluatedCondition(condition, Measure.Level.ERROR, value));
String actualJson = new QualityGateDetailsData(Measure.Level.OK, evaluatedConditions).toJson();

JsonAssert.assertJson(actualJson).isSimilarTo("{" +
"\"level\":\"OK\"," +
"\"conditions\":[" +
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
" \"period\":10," +
" \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
" \"level\":\"OK\"" +
" }," +
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
" \"period\":10," +
" \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
" \"level\":\"WARN\"" +
" }," +
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
" \"period\":10," +
" \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
" \"level\":\"ERROR\"" +
" }" +
"]" +
"}");
"\"level\":\"OK\"," +
"\"conditions\":[" +
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
" \"period\":1," +
" \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
" \"level\":\"OK\"" +
" }," +
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
" \"period\":1," +
" \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
" \"level\":\"WARN\"" +
" }," +
" {" +
" \"metric\":\"key1\"," +
" \"op\":\"GT\"," +
" \"period\":1," +
" \"warning\":\"warnTh\"," +
" \"error\":\"errorTh\"," +
" \"actual\":\"actualValue\"," +
" \"level\":\"ERROR\"" +
" }" +
"]" +
"}");
}
}

+ 14
- 31
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/ConditionEvaluatorTest.java View File

@@ -25,7 +25,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.server.computation.task.projectanalysis.measure.Measure;
import org.sonar.server.computation.task.projectanalysis.measure.MeasureVariations;
import org.sonar.server.computation.task.projectanalysis.metric.Metric;
import org.sonar.server.computation.task.projectanalysis.metric.MetricImpl;

@@ -242,8 +241,8 @@ public class ConditionEvaluatorTest {
assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), measure)).hasLevel(ERROR);
assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.1"), measure)).hasLevel(OK);

assertThat(underTest.evaluate(new Condition(metric, EQUALS.getDbValue(), "10.3", "10.2", null), measure)).hasLevel(Measure.Level.WARN);
assertThat(underTest.evaluate(new Condition(metric, LESS_THAN.getDbValue(), "10.3", "10.2", null), measure)).hasLevel(Measure.Level.ERROR);
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);
}

@Test
@@ -271,34 +270,18 @@ public class ConditionEvaluatorTest {
public void test_condition_on_period() {
for (MetricType metricType : ImmutableList.of(FLOAT, INT, WORK_DUR)) {
Metric metric = createMetric(metricType);
Measure measure = newMeasureBuilder().setVariations(new MeasureVariations(null, 3d, 4d, null, null)).createNoValue();
Measure measure = newMeasureBuilder().setVariation(3d).createNoValue();

assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null, 2), measure)).hasLevel(OK);
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "2", null, 2), measure)).hasLevel(ERROR);
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "4", null, 3), measure)).hasLevel(OK);
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null, 3), measure)).hasLevel(ERROR);
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null, true), measure)).hasLevel(OK);
}
}

@Test
public void condition_on_period_without_value_is_OK() {
Metric metric = createMetric(FLOAT);
Measure measure = newMeasureBuilder().setVariations(new MeasureVariations(null, 3d, 4d, null, null)).createNoValue();
Measure measure = newMeasureBuilder().createNoValue();

assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null, 1), measure)).hasLevel(OK).hasValue(null);
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null, 4), measure)).hasLevel(OK);
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null, 5), measure)).hasLevel(OK);
}

@Test
public void evaluate_throws_IAE_if_condition_is_on_invalid_period() {
Metric metric = createMetric(FLOAT);
Measure measure = newMeasureBuilder().setVariations(new MeasureVariations(null, 3d, 4d, null, null)).createNoValue();

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Following index period is not allowed : 50");

underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null, 50), measure);
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "3", null, true), measure)).hasLevel(OK).hasValue(null);
}

@Test
@@ -306,29 +289,29 @@ public class ConditionEvaluatorTest {
Metric metric = createMetric(RATING);
Measure measure = newMeasureBuilder().create(4, "D");

assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "4", null, null), measure)).hasLevel(OK).hasValue(4);
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "2", null, null), measure)).hasLevel(ERROR).hasValue(4);
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);
}

@Test
public void test_condition_on_rating_on_leak_period() throws Exception {
Metric metric = createMetric(RATING);
Measure measure = newMeasureBuilder().setVariations(new MeasureVariations(4d, null, null, null, null)).createNoValue();
Measure measure = newMeasureBuilder().setVariation(4d).createNoValue();

assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "5", null, 1), measure)).hasLevel(OK).hasValue(4);
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "2", null, 1), measure)).hasLevel(ERROR).hasValue(4);
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);
}

@Test
public void test_condition_on_rating_on_leak_period_when_variation_is_zero() throws Exception {
Metric metric = createMetric(RATING);
Measure measure = newMeasureBuilder().setVariations(new MeasureVariations(0d, null, null, null, null)).createNoValue();
Measure measure = newMeasureBuilder().setVariation(0d).createNoValue();

assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "4", null, 1), measure)).hasLevel(OK).hasValue(0);
assertThat(underTest.evaluate(new Condition(metric, GREATER_THAN.getDbValue(), "4", null, true), measure)).hasLevel(OK).hasValue(0);
}

private static Condition createErrorCondition(Metric metric, Condition.Operator operator, String errorThreshold) {
return new Condition(metric, operator.getDbValue(), errorThreshold, null, null);
return new Condition(metric, operator.getDbValue(), errorThreshold, null, false);
}

private static MetricImpl createMetric(MetricType metricType) {

+ 7
- 8
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/ConditionTest.java View File

@@ -38,12 +38,12 @@ public class ConditionTest {

@Test(expected = NullPointerException.class)
public void constructor_throws_NPE_for_null_metric_argument() {
new Condition(null, SOME_OPERATOR, null, null, null);
new Condition(null, SOME_OPERATOR, null, null, false);
}

@Test(expected = NullPointerException.class)
public void constructor_throws_NPE_for_null_operator_argument() {
new Condition(SOME_METRIC, null, null, null, null);
new Condition(SOME_METRIC, null, null, null, false);
}

@Test
@@ -51,20 +51,19 @@ public class ConditionTest {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Unsupported operator value: 'troloto'");

new Condition(SOME_METRIC, "troloto", null, null, null);
new Condition(SOME_METRIC, "troloto", null, null, false);
}

@Test
public void verify_getters() {
Integer period = 1;
String error = "error threshold";
String warning = "warning threshold";

Condition condition = new Condition(SOME_METRIC, SOME_OPERATOR, error, warning, period);
Condition condition = new Condition(SOME_METRIC, SOME_OPERATOR, error, warning, true);

assertThat(condition.getMetric()).isSameAs(SOME_METRIC);
assertThat(condition.getOperator()).isSameAs(Condition.Operator.EQUALS);
assertThat(condition.getPeriod()).isEqualTo(period);
assertThat(condition.hasPeriod()).isTrue();
assertThat(condition.getErrorThreshold()).isEqualTo(error);
assertThat(condition.getWarningThreshold()).isEqualTo(warning);
}
@@ -73,8 +72,8 @@ public class ConditionTest {
public void all_fields_are_displayed_in_toString() {
when(SOME_METRIC.toString()).thenReturn("metric1");

assertThat(new Condition(SOME_METRIC, SOME_OPERATOR, "error_l", "warn", 1).toString())
.isEqualTo("Condition{metric=metric1, period=1, operator=EQUALS, warningThreshold=warn, errorThreshold=error_l}");
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}");

}


+ 7
- 7
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/EvaluationResultTextConverterTest.java View File

@@ -49,7 +49,7 @@ import static org.sonar.server.computation.task.projectanalysis.measure.Measure.
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, null);
private static final Condition EQ_10_CONDITION = new Condition(INT_METRIC, Condition.Operator.EQUALS.getDbValue(), "10", null, false);
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";
@@ -98,7 +98,7 @@ public class EvaluationResultTextConverterTest {
when(i18n.message(Locale.ENGLISH, "metric." + INT_METRIC.getKey() + ".name", INT_METRIC.getName()))
.thenReturn(metricMsg);

Condition condition = new Condition(INT_METRIC, operator.getDbValue(), ERROR_THRESHOLD, WARNING_THRESHOLD, null);
Condition condition = new Condition(INT_METRIC, operator.getDbValue(), ERROR_THRESHOLD, WARNING_THRESHOLD, false);

assertThat(underTest.asText(condition, new EvaluationResult(level, null)))
.isEqualTo(metricMsg + " " + toSign(operator) + " " + getThreshold(level));
@@ -116,7 +116,7 @@ public class EvaluationResultTextConverterTest {
when(i18n.message(Locale.ENGLISH, "metric." + SOME_VARIATION_METRIC.getKey() + ".name", SOME_VARIATION_METRIC.getName()))
.thenReturn(metricMsg);

Condition condition = new Condition(SOME_VARIATION_METRIC, operator.getDbValue(), ERROR_THRESHOLD, WARNING_THRESHOLD, null);
Condition condition = new Condition(SOME_VARIATION_METRIC, operator.getDbValue(), ERROR_THRESHOLD, WARNING_THRESHOLD, false);

assertThat(underTest.asText(condition, new EvaluationResult(level, null)))
.isEqualTo(metricMsg + " " + toSign(operator) + " " + getThreshold(level));
@@ -134,10 +134,10 @@ public class EvaluationResultTextConverterTest {

Date date = new Date();
Period period = new Period(periodIndex, SOME_MODE, null, date.getTime(), SOME_ANALYSIS_UUID);
periodsHolder.setPeriods(period);
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, periodIndex);
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);
@@ -157,10 +157,10 @@ public class EvaluationResultTextConverterTest {

Date date = new Date();
Period period = new Period(periodIndex, SOME_MODE, null, date.getTime(), SOME_ANALYSIS_UUID);
periodsHolder.setPeriods(period);
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, periodIndex);
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);

+ 4
- 4
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/QualityGateServiceImplTest.java View File

@@ -43,7 +43,8 @@ public class QualityGateServiceImplTest {
private static final long METRIC_ID_2 = 753;
private static final Metric METRIC_1 = mock(Metric.class);
private static final Metric METRIC_2 = mock(Metric.class);
private static final QualityGateConditionDto CONDITION_1 = new QualityGateConditionDto().setId(321).setMetricId(METRIC_ID_1).setOperator("EQ").setPeriod(1).setWarningThreshold("warnin_th").setErrorThreshold("error_th");
private static final QualityGateConditionDto CONDITION_1 = new QualityGateConditionDto().setId(321).setMetricId(METRIC_ID_1).setOperator("EQ").setPeriod(1)
.setWarningThreshold("warnin_th").setErrorThreshold("error_th");
private static final QualityGateConditionDto CONDITION_2 = new QualityGateConditionDto().setId(456).setMetricId(METRIC_ID_2).setOperator("NE");

private QualityGateDao qualityGateDao = mock(QualityGateDao.class);
@@ -83,8 +84,7 @@ public class QualityGateServiceImplTest {
assertThat(res.get().getId()).isEqualTo(SOME_ID);
assertThat(res.get().getName()).isEqualTo(SOME_NAME);
assertThat(res.get().getConditions()).containsOnly(
new Condition(METRIC_1, CONDITION_1.getOperator(), CONDITION_1.getErrorThreshold(), CONDITION_1.getWarningThreshold(), CONDITION_1.getPeriod()),
new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold(), CONDITION_2.getWarningThreshold(), CONDITION_2.getPeriod())
);
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));
}
}

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/QualityGateEventsStepTest.java View File

@@ -25,9 +25,9 @@ import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.sonar.api.notifications.Notification;
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.server.computation.task.projectanalysis.event.Event;
import org.sonar.server.computation.task.projectanalysis.event.EventRepository;
import org.sonar.server.computation.task.projectanalysis.measure.Measure;

+ 12
- 12
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/QualityGateMeasuresStepTest.java View File

@@ -32,9 +32,9 @@ import org.junit.rules.ExpectedException;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.server.computation.task.projectanalysis.measure.Measure;
import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule;
import org.sonar.server.computation.task.projectanalysis.measure.qualitygatedetails.EvaluatedCondition;
@@ -58,10 +58,10 @@ import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder;
import static org.sonar.server.computation.task.projectanalysis.measure.Measure.Level.ERROR;
import static org.sonar.server.computation.task.projectanalysis.measure.Measure.Level.OK;
import static org.sonar.server.computation.task.projectanalysis.measure.Measure.Level.WARN;
import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder;
import static org.sonar.server.computation.task.projectanalysis.measure.MeasureAssert.assertThat;
import static org.sonar.server.computation.task.projectanalysis.measure.MeasureVariations.newMeasureVariationsBuilder;

@@ -279,7 +279,7 @@ public class QualityGateMeasuresStepTest {
public void new_measure_has_ERROR_level_of_all_conditions_for_a_specific_metric_if_its_the_worst() {
int rawValue = 1;
Condition fixedCondition = createEqualsCondition(INT_METRIC_1, "1", null);
Condition periodCondition = createEqualsCondition(INT_METRIC_1, null, "2", 1);
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().create(rawValue, null);
@@ -297,7 +297,7 @@ public class QualityGateMeasuresStepTest {
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", 1);
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()
@@ -317,20 +317,20 @@ public class QualityGateMeasuresStepTest {
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, 1);
Condition periodCondition = createEqualsCondition(INT_METRIC_1, "1", null, true);

qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_ID, SOME_QG_NAME, of(fixedCondition, periodCondition)));
Measure measure = newMeasureBuilder()
.setVariations(newMeasureVariationsBuilder().setVariation(new Period(1, "mode", null, 1212, "u1"), rawValue).build())
.create(rawValue, null);
.setVariation(rawValue)
.create(rawValue, null);
measureRepository.addRawMeasure(PROJECT_REF, INT_METRIC_1_KEY, measure);

underTest.execute();

Optional<Measure> rawMeasure1 = measureRepository.getAddedRawMeasure(PROJECT_REF, INT_METRIC_1_KEY);
assertThat(rawMeasure1.get())
.hasQualityGateLevel(ERROR)
.hasQualityGateText(dumbResultTextAnswer(periodCondition, ERROR, rawValue));
.hasQualityGateLevel(ERROR)
.hasQualityGateText(dumbResultTextAnswer(periodCondition, ERROR, rawValue));
}

private Measure getAlertStatusMeasure() {
@@ -342,11 +342,11 @@ public class QualityGateMeasuresStepTest {
}

private static Condition createEqualsCondition(Metric metric, @Nullable String errorThreshold, @Nullable String warningThreshold) {
return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), errorThreshold, warningThreshold, null);
return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), errorThreshold, warningThreshold, false);
}

private static Condition createEqualsCondition(Metric metric, @Nullable String errorThreshold, @Nullable String warningThreshold, @Nullable Integer period) {
return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), errorThreshold, warningThreshold, period);
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);
}

private static MetricImpl createIntMetric(int index) {

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputeMeasureVariationsStepTest.java View File

@@ -31,10 +31,10 @@ import org.sonar.db.component.ComponentTesting;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.measure.MeasureDto;
import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.DumbDeveloper;
import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.server.computation.task.projectanalysis.measure.Measure;
import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule;
import org.sonar.server.computation.task.projectanalysis.measure.MeasureVariations;

Loading…
Cancel
Save