Skip to content

Commit

Permalink
SONAR-7276 support multiple conditions for a given metric in QG
Browse files Browse the repository at this point in the history
they must have a different period
  • Loading branch information
sns-seb committed May 12, 2016
1 parent ffa4f63 commit b6dc9d3
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 85 deletions.
Expand Up @@ -22,7 +22,10 @@
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap; 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.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
Expand Down Expand Up @@ -69,6 +72,8 @@
* It must be executed after the computation of differential measures {@link ComputeMeasureVariationsStep} * It must be executed after the computation of differential measures {@link ComputeMeasureVariationsStep}
*/ */
public class QualityGateMeasuresStep implements ComputationStep { public class QualityGateMeasuresStep implements ComputationStep {
private static final Ordering<Condition> PERIOD_ORDERING = Ordering.natural().nullsLast()
.onResultOf(ConditionToPeriod.INSTANCE);


private final TreeRootHolder treeRootHolder; private final TreeRootHolder treeRootHolder;
private final QualityGateHolder qualityGateHolder; private final QualityGateHolder qualityGateHolder;
Expand Down Expand Up @@ -164,24 +169,37 @@ private static Map<Condition, ConditionStatus> createStatusPerCondition(Iterable
} }


private void updateMeasures(Component project, Set<Condition> conditions, QualityGateDetailsDataBuilder builder) { private void updateMeasures(Component project, Set<Condition> conditions, QualityGateDetailsDataBuilder builder) {
for (Condition condition : conditions) { Multimap<Metric, Condition> conditionsPerMetric = from(conditions).index(ConditionToMetric.INSTANCE);
Optional<Measure> measure = measureRepository.getRawMeasure(project, condition.getMetric()); for (Map.Entry<Metric, Collection<Condition>> entry : conditionsPerMetric.asMap().entrySet()) {
Metric metric = entry.getKey();
Optional<Measure> measure = measureRepository.getRawMeasure(project, metric);
if (!measure.isPresent()) { if (!measure.isPresent()) {
continue; continue;
} }


EvaluationResult evaluationResult = new ConditionEvaluator().evaluate(condition, measure.get()); MetricEvaluationResult metricEvaluationResult = evaluateQualityGate(measure.get(), entry.getValue());

String text = evaluationResultTextConverter.asText(metricEvaluationResult.condition, metricEvaluationResult.evaluationResult);
String text = evaluationResultTextConverter.asText(condition, evaluationResult);
builder.addLabel(text); builder.addLabel(text);


Measure updatedMeasure = Measure.updatedMeasureBuilder(measure.get()) Measure updatedMeasure = Measure.updatedMeasureBuilder(measure.get())
.setQualityGateStatus(new QualityGateStatus(evaluationResult.getLevel(), text)) .setQualityGateStatus(new QualityGateStatus(metricEvaluationResult.evaluationResult.getLevel(), text))
.create(); .create();
measureRepository.update(project, condition.getMetric(), updatedMeasure); measureRepository.update(project, metric, updatedMeasure);

builder.addEvaluatedCondition(metricEvaluationResult);
}
}


builder.addEvaluatedCondition(condition, evaluationResult); private static MetricEvaluationResult evaluateQualityGate(Measure measure, Collection<Condition> conditions) {
ConditionEvaluator conditionEvaluator = new ConditionEvaluator();
MetricEvaluationResult metricEvaluationResult = null;
for (Condition newCondition : PERIOD_ORDERING.immutableSortedCopy(conditions)) {
EvaluationResult newEvaluationResult = conditionEvaluator.evaluate(newCondition, measure);
if (metricEvaluationResult == null || newEvaluationResult.getLevel().ordinal() > metricEvaluationResult.evaluationResult.getLevel().ordinal()) {
metricEvaluationResult = new MetricEvaluationResult(newEvaluationResult, newCondition);
}
} }
return metricEvaluationResult;
} }


private void addProjectMeasure(Component project, QualityGateDetailsDataBuilder builder) { private void addProjectMeasure(Component project, QualityGateDetailsDataBuilder builder) {
Expand Down Expand Up @@ -221,14 +239,16 @@ public List<String> getLabels() {
return labels; return labels;
} }


public void addEvaluatedCondition(Condition condition, EvaluationResult evaluationResult) { public void addEvaluatedCondition(MetricEvaluationResult metricEvaluationResult) {
if (Measure.Level.WARN == evaluationResult.getLevel() && this.globalLevel != Measure.Level.ERROR) { Measure.Level level = metricEvaluationResult.evaluationResult.getLevel();
if (Measure.Level.WARN == level && this.globalLevel != Measure.Level.ERROR) {
globalLevel = Measure.Level.WARN; globalLevel = Measure.Level.WARN;


} else if (Measure.Level.ERROR == evaluationResult.getLevel()) { } else if (Measure.Level.ERROR == level) {
globalLevel = Measure.Level.ERROR; globalLevel = Measure.Level.ERROR;
} }
evaluatedConditions.add(new EvaluatedCondition(condition, evaluationResult.getLevel(), evaluationResult.getValue())); evaluatedConditions.add(
new EvaluatedCondition(metricEvaluationResult.condition, level, metricEvaluationResult.evaluationResult.getValue()));
} }


public List<EvaluatedCondition> getEvaluatedConditions() { public List<EvaluatedCondition> getEvaluatedConditions() {
Expand All @@ -245,4 +265,34 @@ public Condition apply(@Nonnull EvaluatedCondition input) {
return input.getCondition(); return input.getCondition();
} }
} }

private static class MetricEvaluationResult {
private final EvaluationResult evaluationResult;
private final Condition condition;

private MetricEvaluationResult(EvaluationResult evaluationResult, Condition condition) {
this.evaluationResult = evaluationResult;
this.condition = condition;
}
}

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();
}
}
} }

0 comments on commit b6dc9d3

Please sign in to comment.