diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2018-07-02 17:44:49 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2018-07-09 10:39:32 +0200 |
commit | 0dae853007134cfe1343f8fbe6b2046e19b217df (patch) | |
tree | 3c84fb8a57a0fde0d1c22af06c64d4e3649b3ca4 /server/sonar-server | |
parent | 4182b00648ddf1157c271d431c938b53b811a76b (diff) | |
download | sonarqube-0dae853007134cfe1343f8fbe6b2046e19b217df.tar.gz sonarqube-0dae853007134cfe1343f8fbe6b2046e19b217df.zip |
move shared Quality Gate classes to server-common
Diffstat (limited to 'server/sonar-server')
23 files changed, 38 insertions, 846 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/live/LiveQualityGateComputerImpl.java b/server/sonar-server/src/main/java/org/sonar/server/measure/live/LiveQualityGateComputerImpl.java index 431821f0095..b38fd716b5c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/live/LiveQualityGateComputerImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/live/LiveQualityGateComputerImpl.java @@ -46,6 +46,7 @@ import org.sonar.server.qualitygate.QualityGateEvaluator; import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.qualitygate.ShortLivingBranchQualityGate; +import static java.lang.String.format; import static org.sonar.core.util.stream.MoreCollectors.toHashSet; import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; @@ -68,7 +69,9 @@ public class LiveQualityGateComputerImpl implements LiveQualityGateComputer { } ComponentDto mainProject = project.getMainBranchProjectUuid() == null ? project : dbClient.componentDao().selectOrFailByKey(dbSession, project.getKey()); - QualityGateDto gateDto = qGateFinder.getQualityGate(dbSession, organization, mainProject).getQualityGate(); + QualityGateDto gateDto = qGateFinder.getQualityGate(dbSession, organization, mainProject) + .orElseThrow(() -> new IllegalStateException(format("Quality Gate not found for project %s", mainProject.getKey()))) + .getQualityGate(); Collection<QualityGateConditionDto> conditionDtos = dbClient.gateConditionDao().selectForQualityGate(dbSession, gateDto.getId()); Set<Integer> metricIds = conditionDtos.stream().map(c -> (int) c.getMetricId()) .collect(toHashSet(conditionDtos.size())); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ConditionEvaluator.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ConditionEvaluator.java deleted file mode 100644 index f154d3414fd..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ConditionEvaluator.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 java.util.EnumSet; -import java.util.Optional; -import java.util.Set; -import javax.annotation.CheckForNull; -import org.sonar.api.measures.Metric.ValueType; -import org.sonar.server.qualitygate.EvaluatedCondition.EvaluationStatus; - -import static java.util.Optional.of; -import static org.sonar.api.measures.Metric.ValueType.BOOL; -import static org.sonar.api.measures.Metric.ValueType.FLOAT; -import static org.sonar.api.measures.Metric.ValueType.INT; -import static org.sonar.api.measures.Metric.ValueType.MILLISEC; -import static org.sonar.api.measures.Metric.ValueType.PERCENT; -import static org.sonar.api.measures.Metric.ValueType.RATING; -import static org.sonar.api.measures.Metric.ValueType.WORK_DUR; - -class ConditionEvaluator { - - private static final Set<ValueType> NUMERICAL_TYPES = EnumSet.of(BOOL, INT, RATING, FLOAT, MILLISEC, PERCENT, WORK_DUR); - - private ConditionEvaluator() { - // prevent instantiation - } - - /** - * Evaluates the condition for the specified measure - */ - static EvaluatedCondition evaluate(Condition condition, QualityGateEvaluator.Measures measures) { - Optional<QualityGateEvaluator.Measure> measure = measures.get(condition.getMetricKey()); - if (!measure.isPresent()) { - return new EvaluatedCondition(condition, EvaluationStatus.OK, null); - } - - Optional<Comparable> value = getMeasureValue(condition, measure.get()); - if (!value.isPresent()) { - return new EvaluatedCondition(condition, EvaluationStatus.OK, null); - } - - ValueType type = measure.get().getType(); - return evaluateCondition(condition, type, value.get(), true) - .orElseGet(() -> evaluateCondition(condition, type, value.get(), false) - .orElseGet(() -> new EvaluatedCondition(condition, EvaluationStatus.OK, value.get().toString()))); - } - - /** - * Evaluates the error or warning condition. Returns empty if threshold or measure value is not defined. - */ - private static Optional<EvaluatedCondition> evaluateCondition(Condition condition, ValueType type, Comparable value, boolean error) { - Optional<Comparable> threshold = getThreshold(condition, type, error); - if (!threshold.isPresent()) { - return Optional.empty(); - } - - if (reachThreshold(value, threshold.get(), condition)) { - EvaluationStatus status = error ? EvaluationStatus.ERROR : EvaluationStatus.WARN; - return of(new EvaluatedCondition(condition, status, value.toString())); - } - return Optional.empty(); - } - - private static Optional<Comparable> getThreshold(Condition condition, ValueType valueType, boolean error) { - Optional<String> valString = error ? condition.getErrorThreshold() : condition.getWarningThreshold(); - return valString.map(s -> { - try { - switch (valueType) { - case BOOL: - return parseInteger(s) == 1; - case INT: - case RATING: - return parseInteger(s); - case MILLISEC: - case WORK_DUR: - return Long.parseLong(s); - case FLOAT: - case PERCENT: - return Double.parseDouble(s); - case STRING: - case LEVEL: - return s; - default: - throw new IllegalArgumentException(String.format("Unsupported value type %s. Cannot convert condition value", valueType)); - } - } catch (NumberFormatException badValueFormat) { - throw new IllegalArgumentException(String.format( - "Quality Gate: unable to parse threshold '%s' to compare against %s", s, condition.getMetricKey())); - } - }); - } - - private static Optional<Comparable> getMeasureValue(Condition condition, QualityGateEvaluator.Measure measure) { - if (condition.isOnLeakPeriod()) { - return Optional.ofNullable(getLeakValue(measure)); - } - - return Optional.ofNullable(getValue(measure)); - } - - @CheckForNull - private static Comparable getValue(QualityGateEvaluator.Measure measure) { - if (NUMERICAL_TYPES.contains(measure.getType())) { - return measure.getValue().isPresent() ? getNumericValue(measure.getType(), measure.getValue().getAsDouble()) : null; - } - - switch (measure.getType()) { - case LEVEL: - case STRING: - case DISTRIB: - return measure.getStringValue().orElse(null); - default: - throw new IllegalArgumentException("Condition on leak period 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; - } - - throw new IllegalArgumentException("Condition on leak period is not allowed for type " + measure.getType()); - } - - private static Comparable getNumericValue(ValueType type, double value) { - switch (type) { - case BOOL: - return Double.compare(value, 1.0) == 1; - case INT: - case RATING: - return (int) value; - case FLOAT: - case PERCENT: - return value; - case MILLISEC: - case WORK_DUR: - return (long) value; - default: - throw new IllegalArgumentException("Condition on numeric value is not allowed for type " + type); - } - } - - private static int parseInteger(String value) { - return value.contains(".") ? Integer.parseInt(value.substring(0, value.indexOf('.'))) : Integer.parseInt(value); - } - - private static boolean reachThreshold(Comparable measureValue, Comparable threshold, Condition condition) { - int comparison = measureValue.compareTo(threshold); - switch (condition.getOperator()) { - case EQUALS: - return comparison == 0; - case NOT_EQUALS: - return comparison != 0; - case GREATER_THAN: - return comparison > 0; - case LESS_THAN: - return comparison < 0; - default: - throw new IllegalArgumentException(String.format("Unsupported operator '%s'", condition.getOperator())); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateEvaluator.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateEvaluator.java deleted file mode 100644 index 3ecf03d08dd..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateEvaluator.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 java.util.Optional; -import java.util.OptionalDouble; -import java.util.Set; -import org.sonar.api.ce.ComputeEngineSide; -import org.sonar.api.measures.Metric; -import org.sonar.api.server.ServerSide; - -@ComputeEngineSide -@ServerSide -public interface QualityGateEvaluator { - - /** - * @param measures must provide the measures related to the metrics - * defined by {@link #getMetricKeys(QualityGate)} - */ - EvaluatedQualityGate evaluate(QualityGate gate, Measures measures); - - /** - * Keys of the metrics involved in the computation of gate status. - * It may include metrics that are not part of conditions, - * for instance "new_lines" for the circuit-breaker on - * small changesets. - */ - Set<String> getMetricKeys(QualityGate gate); - - interface Measures { - Optional<Measure> get(String metricKey); - } - - interface Measure { - Metric.ValueType getType(); - - OptionalDouble getValue(); - - Optional<String> getStringValue(); - - OptionalDouble getLeakValue(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateEvaluatorImpl.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateEvaluatorImpl.java deleted file mode 100644 index f0ce9449320..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateEvaluatorImpl.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 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 { - - private static final int MAXIMUM_NEW_LINES_FOR_SMALL_CHANGESETS = 20; - /** - * Some metrics will be ignored on very small change sets. - */ - private static final Set<String> METRICS_TO_IGNORE_ON_SMALL_CHANGESETS = ImmutableSet.of( - CoreMetrics.NEW_COVERAGE_KEY, - CoreMetrics.NEW_LINE_COVERAGE_KEY, - CoreMetrics.NEW_BRANCH_COVERAGE_KEY, - CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_KEY, - CoreMetrics.NEW_DUPLICATED_LINES_KEY, - CoreMetrics.NEW_BLOCKS_DUPLICATED_KEY); - - @Override - public EvaluatedQualityGate evaluate(QualityGate gate, Measures measures) { - EvaluatedQualityGate.Builder result = EvaluatedQualityGate.newBuilder() - .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); - - 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))); - result.setIgnoredConditionsOnSmallChangeset(true); - } else { - result.addCondition(evaluation); - } - } - - result.setStatus(overallStatusOf(result.getEvaluatedConditions())); - - return result.build(); - } - - @Override - public Set<String> getMetricKeys(QualityGate gate) { - Set<String> metricKeys = new HashSet<>(); - metricKeys.add(CoreMetrics.NEW_LINES_KEY); - for (Condition condition : gate.getConditions()) { - metricKeys.add(condition.getMetricKey()); - } - return metricKeys; - } - - 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; - } - - private static Level overallStatusOf(Set<EvaluatedCondition> conditions) { - Set<EvaluationStatus> statuses = conditions.stream().map(EvaluatedCondition::getStatus).collect(toEnumSet(EvaluationStatus.class)); - if (statuses.contains(EvaluationStatus.ERROR)) { - return Level.ERROR; - } - if (statuses.contains(EvaluationStatus.WARN)) { - return Level.WARN; - } - return Level.OK; - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java deleted file mode 100644 index 89b7e64783e..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 java.util.Optional; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.qualitygate.QGateWithOrgDto; -import org.sonar.db.qualitygate.QualityGateDto; - -import static com.google.common.base.Preconditions.checkState; -import static org.sonar.server.ws.WsUtils.checkFound; - -public class QualityGateFinder { - - public static final String SONAR_QUALITYGATE_PROPERTY = "sonar.qualitygate"; - - private final DbClient dbClient; - - public QualityGateFinder(DbClient dbClient) { - this.dbClient = dbClient; - } - - /** - * Return effective quality gate of a project. - * - * It will first try to get the quality gate explicitly defined on a project, if none it will try to return default quality gate of the organization - */ - public QualityGateData getQualityGate(DbSession dbSession, OrganizationDto organization, ComponentDto component) { - Optional<Long> qualityGateId = dbClient.projectQgateAssociationDao().selectQGateIdByComponentId(dbSession, component.getId()); - if (qualityGateId.isPresent()) { - QualityGateDto qualityGate = checkFound(dbClient.qualityGateDao().selectById(dbSession, qualityGateId.get()), "No quality gate has been found for id %s", qualityGateId); - return new QualityGateData(qualityGate, false); - } - QualityGateDto defaultQualityGate = dbClient.qualityGateDao().selectByOrganizationAndUuid(dbSession, organization, organization.getDefaultQualityGateUuid()); - checkState(defaultQualityGate != null, "Unable to find the quality gate [%s] for organization [%s]", organization.getDefaultQualityGateUuid(), organization.getUuid()); - return new QualityGateData(defaultQualityGate, true); - } - - public QGateWithOrgDto getByOrganizationAndId(DbSession dbSession, OrganizationDto organization, long qualityGateId) { - return checkFound(dbClient.qualityGateDao().selectByOrganizationAndId(dbSession, organization, qualityGateId), - "No quality gate has been found for id %s in organization %s", qualityGateId, organization.getName()); - } - - public QualityGateDto getDefault(DbSession dbSession, OrganizationDto organization) { - QGateWithOrgDto qgate = dbClient.qualityGateDao().selectByOrganizationAndUuid(dbSession, organization, organization.getDefaultQualityGateUuid()); - checkState(qgate != null, "Default quality gate [%s] is missing on organization [%s]", organization.getDefaultQualityGateUuid(), organization.getUuid()); - return qgate; - } - - public QualityGateDto getBuiltInQualityGate(DbSession dbSession) { - QualityGateDto builtIn = dbClient.qualityGateDao().selectBuiltIn(dbSession); - checkState(builtIn != null, "Builtin quality gate is missing."); - return builtIn; - } - - public static class QualityGateData { - private final QualityGateDto qualityGate; - private final boolean isDefault; - - private QualityGateData(QualityGateDto qualityGate, boolean isDefault) { - this.qualityGate = qualityGate; - this.isDefault = isDefault; - } - - public QualityGateDto getQualityGate() { - return qualityGate; - } - - public boolean isDefault() { - return isDefault; - } - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java index 070c7651ae0..9b21a9ae6bd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java @@ -26,7 +26,6 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.qualitygate.QualityGateUpdater; import org.sonar.server.user.UserSession; @@ -43,15 +42,13 @@ public class CopyAction implements QualityGatesWsAction { private final DbClient dbClient; private final UserSession userSession; private final QualityGateUpdater qualityGateUpdater; - private final QualityGateFinder qualityGateFinder; private final QualityGatesWsSupport wsSupport; public CopyAction(DbClient dbClient, UserSession userSession, QualityGateUpdater qualityGateUpdater, - QualityGateFinder qualityGateFinder, QualityGatesWsSupport wsSupport) { + QualityGatesWsSupport wsSupport) { this.dbClient = dbClient; this.userSession = userSession; this.qualityGateUpdater = qualityGateUpdater; - this.qualityGateFinder = qualityGateFinder; this.wsSupport = wsSupport; } @@ -88,7 +85,7 @@ public class CopyAction implements QualityGatesWsAction { OrganizationDto organization = wsSupport.getOrganization(dbSession, request); userSession.checkPermission(ADMINISTER_QUALITY_GATES, organization); - QualityGateDto qualityGate = qualityGateFinder.getByOrganizationAndId(dbSession, organization, id); + QualityGateDto qualityGate = wsSupport.getByOrganizationAndId(dbSession, organization, id); QualityGateDto copy = qualityGateUpdater.copy(dbSession, organization, qualityGate, destinationName); dbSession.commit(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java index 0b40b6c776e..86fb85dc47f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java @@ -28,7 +28,6 @@ import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualitygate.QGateWithOrgDto; import org.sonar.db.qualitygate.QualityGateConditionDto; import org.sonar.server.qualitygate.QualityGateConditionsUpdater; -import org.sonar.server.qualitygate.QualityGateFinder; import org.sonarqube.ws.Qualitygates.CreateConditionResponse; import static com.google.common.base.Strings.emptyToNull; @@ -47,13 +46,11 @@ public class CreateConditionAction implements QualityGatesWsAction { private final DbClient dbClient; private final QualityGateConditionsUpdater qualityGateConditionsUpdater; - private final QualityGateFinder qualityGateFinder; private final QualityGatesWsSupport wsSupport; - public CreateConditionAction(DbClient dbClient, QualityGateConditionsUpdater qualityGateConditionsUpdater, QualityGateFinder qualityGateFinder, QualityGatesWsSupport wsSupport) { + public CreateConditionAction(DbClient dbClient, QualityGateConditionsUpdater qualityGateConditionsUpdater, QualityGatesWsSupport wsSupport) { this.dbClient = dbClient; this.qualityGateConditionsUpdater = qualityGateConditionsUpdater; - this.qualityGateFinder = qualityGateFinder; this.wsSupport = wsSupport; } @@ -88,7 +85,7 @@ public class CreateConditionAction implements QualityGatesWsAction { try (DbSession dbSession = dbClient.openSession(false)) { OrganizationDto organization = wsSupport.getOrganization(dbSession, request); - QGateWithOrgDto qualityGate = qualityGateFinder.getByOrganizationAndId(dbSession, organization, gateId); + QGateWithOrgDto qualityGate = wsSupport.getByOrganizationAndId(dbSession, organization, gateId); wsSupport.checkCanEdit(qualityGate); QualityGateConditionDto condition = qualityGateConditionsUpdater.createCondition(dbSession, qualityGate, metric, operator, emptyToNull(warning), emptyToNull(error), period); CreateConditionResponse.Builder createConditionResponse = CreateConditionResponse.newBuilder() diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java index 5b71c51c0d4..60e6d5eeebf 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java @@ -66,7 +66,7 @@ public class DestroyAction implements QualityGatesWsAction { long qualityGateId = request.mandatoryParamAsLong(QualityGatesWsParameters.PARAM_ID); try (DbSession dbSession = dbClient.openSession(false)) { OrganizationDto organization = wsSupport.getOrganization(dbSession, request); - QGateWithOrgDto qualityGate = finder.getByOrganizationAndId(dbSession, organization, qualityGateId); + QGateWithOrgDto qualityGate = wsSupport.getByOrganizationAndId(dbSession, organization, qualityGateId); QualityGateDto defaultQualityGate = finder.getDefault(dbSession, organization); checkArgument(!defaultQualityGate.getId().equals(qualityGate.getId()), "The default quality gate cannot be removed"); wsSupport.checkCanEdit(qualityGate); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java index 5b78ed31c9f..afc5c057c95 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java @@ -29,11 +29,13 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualitygate.QualityGateDto; import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.qualitygate.QualityGateFinder.QualityGateData; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Qualitygates.GetByProjectResponse; +import static java.lang.String.format; import static org.sonar.api.web.UserRole.ADMIN; import static org.sonar.api.web.UserRole.USER; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_GET_BY_PROJECT; @@ -75,8 +77,7 @@ public class GetByProjectAction implements QualityGatesWsAction { .setChangelog( new Change("6.6", "The parameter 'projectId' has been removed"), new Change("6.6", "The parameter 'projectKey' has been renamed to 'project'"), - new Change("6.6", "This webservice is now part of the public API") - ); + new Change("6.6", "This webservice is now part of the public API")); action.createParam(PARAM_PROJECT) .setDescription("Project key") @@ -99,7 +100,8 @@ public class GetByProjectAction implements QualityGatesWsAction { throw insufficientPrivilegesException(); } - QualityGateData data = qualityGateFinder.getQualityGate(dbSession, organization, project); + QualityGateData data = qualityGateFinder.getQualityGate(dbSession, organization, project) + .orElseThrow(() -> new NotFoundException(format("Quality gate not found for project %s", project.getKey()))); writeProtobuf(buildResponse(data), request, response); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java index 2279e4263d6..58685554fbc 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java @@ -57,6 +57,12 @@ public class QualityGatesWsSupport { this.defaultOrganizationProvider = defaultOrganizationProvider; } + public QGateWithOrgDto getByOrganizationAndId(DbSession dbSession, OrganizationDto organization, long qualityGateId) { + return checkFound( + dbClient.qualityGateDao().selectByOrganizationAndId(dbSession, organization, qualityGateId), + "No quality gate has been found for id %s in organization %s", qualityGateId, organization.getName()); + } + QualityGateConditionDto getCondition(DbSession dbSession, long id) { return checkFound(dbClient.gateConditionDao().selectById(id, dbSession), "No quality gate condition with id '%d'", id); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java index eac5f039c9b..d94ab3e4dee 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java @@ -27,7 +27,6 @@ import org.sonar.db.DbSession; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualitygate.QGateWithOrgDto; import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.qualitygate.QualityGateFinder; import org.sonarqube.ws.Qualitygates.QualityGate; import static com.google.common.base.Preconditions.checkArgument; @@ -41,12 +40,10 @@ import static org.sonar.server.ws.WsUtils.writeProtobuf; public class RenameAction implements QualityGatesWsAction { private final DbClient dbClient; - private final QualityGateFinder qualityGateFinder; private final QualityGatesWsSupport wsSupport; - public RenameAction(DbClient dbClient, QualityGateFinder qualityGateFinder, QualityGatesWsSupport wsSupport) { + public RenameAction(DbClient dbClient, QualityGatesWsSupport wsSupport) { this.dbClient = dbClient; - this.qualityGateFinder = qualityGateFinder; this.wsSupport = wsSupport; } @@ -87,7 +84,7 @@ public class RenameAction implements QualityGatesWsAction { } private QualityGateDto rename(DbSession dbSession, OrganizationDto organization, long id, String name) { - QGateWithOrgDto qualityGate = qualityGateFinder.getByOrganizationAndId(dbSession, organization, id); + QGateWithOrgDto qualityGate = wsSupport.getByOrganizationAndId(dbSession, organization, id); wsSupport.checkCanEdit(qualityGate); checkArgument(!isNullOrEmpty(name), CANT_BE_EMPTY_MESSAGE, "Name"); checkNotAlreadyExists(dbSession, organization, qualityGate, name); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java index 1d1e66273e9..5f33779566d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java @@ -35,7 +35,6 @@ import org.sonar.db.qualitygate.ProjectQgateAssociation; import org.sonar.db.qualitygate.ProjectQgateAssociationDto; import org.sonar.db.qualitygate.ProjectQgateAssociationQuery; import org.sonar.db.qualitygate.QGateWithOrgDto; -import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Qualitygates; @@ -52,13 +51,11 @@ public class SearchAction implements QualityGatesWsAction { private final DbClient dbClient; private final UserSession userSession; - private QualityGateFinder qualityGateFinder; private final QualityGatesWsSupport wsSupport; - public SearchAction(DbClient dbClient, UserSession userSession, QualityGateFinder qualityGateFinder, QualityGatesWsSupport wsSupport) { + public SearchAction(DbClient dbClient, UserSession userSession, QualityGatesWsSupport wsSupport) { this.dbClient = dbClient; this.userSession = userSession; - this.qualityGateFinder = qualityGateFinder; this.wsSupport = wsSupport; } @@ -99,7 +96,7 @@ public class SearchAction implements QualityGatesWsAction { try (DbSession dbSession = dbClient.openSession(false)) { OrganizationDto organization = wsSupport.getOrganization(dbSession, request); - QGateWithOrgDto qualityGate = qualityGateFinder.getByOrganizationAndId(dbSession, organization, request.mandatoryParamAsLong(PARAM_GATE_ID)); + QGateWithOrgDto qualityGate = wsSupport.getByOrganizationAndId(dbSession, organization, request.mandatoryParamAsLong(PARAM_GATE_ID)); Association associations = find(dbSession, ProjectQgateAssociationQuery.builder() .qualityGate(qualityGate) diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java index 0f02ccd8cbc..94606de76d6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java @@ -33,7 +33,6 @@ import org.sonar.db.property.PropertyDto; import org.sonar.db.qualitygate.QGateWithOrgDto; import org.sonar.server.component.ComponentFinder; import org.sonar.server.component.ComponentFinder.ParamNames; -import org.sonar.server.qualitygate.QualityGateFinder; import static org.sonar.server.qualitygate.QualityGateFinder.SONAR_QUALITYGATE_PROPERTY; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_SELECT; @@ -46,13 +45,11 @@ public class SelectAction implements QualityGatesWsAction { private final DbClient dbClient; private final ComponentFinder componentFinder; private final QualityGatesWsSupport wsSupport; - private final QualityGateFinder qualityGateFinder; - public SelectAction(DbClient dbClient, ComponentFinder componentFinder, QualityGatesWsSupport wsSupport, QualityGateFinder qualityGateFinder) { + public SelectAction(DbClient dbClient, ComponentFinder componentFinder, QualityGatesWsSupport wsSupport) { this.dbClient = dbClient; this.componentFinder = componentFinder; this.wsSupport = wsSupport; - this.qualityGateFinder = qualityGateFinder; } @Override @@ -93,7 +90,7 @@ public class SelectAction implements QualityGatesWsAction { try (DbSession dbSession = dbClient.openSession(false)) { OrganizationDto organization = wsSupport.getOrganization(dbSession, request); - QGateWithOrgDto qualityGate = qualityGateFinder.getByOrganizationAndId(dbSession, organization, gateId); + QGateWithOrgDto qualityGate = wsSupport.getByOrganizationAndId(dbSession, organization, gateId); ComponentDto project = getProject(dbSession, organization, projectId, projectKey); wsSupport.checkCanAdminProject(organization, project); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java index ef624a989df..771cfa0436e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java @@ -26,7 +26,6 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.user.UserSession; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES; @@ -37,14 +36,11 @@ public class SetAsDefaultAction implements QualityGatesWsAction { private final DbClient dbClient; private final UserSession userSession; - private final QualityGateFinder qualityGateFinder; private final QualityGatesWsSupport wsSupport; - public SetAsDefaultAction(DbClient dbClient, UserSession userSession, - QualityGateFinder qualityGateFinder, QualityGatesWsSupport qualityGatesWsSupport) { + public SetAsDefaultAction(DbClient dbClient, UserSession userSession, QualityGatesWsSupport qualityGatesWsSupport) { this.dbClient = dbClient; this.userSession = userSession; - this.qualityGateFinder = qualityGateFinder; this.wsSupport = qualityGatesWsSupport; } @@ -72,7 +68,7 @@ public class SetAsDefaultAction implements QualityGatesWsAction { try (DbSession dbSession = dbClient.openSession(false)) { OrganizationDto organization = wsSupport.getOrganization(dbSession, request); userSession.checkPermission(ADMINISTER_QUALITY_GATES, organization); - QualityGateDto qualityGate = qualityGateFinder.getByOrganizationAndId(dbSession, organization, id); + QualityGateDto qualityGate = wsSupport.getByOrganizationAndId(dbSession, organization, id); organization.setDefaultQualityGateUuid(qualityGate.getUuid()); dbClient.organizationDao().update(dbSession, organization); dbSession.commit(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java index 4c2e3d988eb..4df89144a66 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java @@ -104,7 +104,7 @@ public class ShowAction implements QualityGatesWsAction { return checkFound(dbClient.qualityGateDao().selectByOrganizationAndName(dbSession, organization, name), "No quality gate has been found for name %s", name); } if (id != null) { - return qualityGateFinder.getByOrganizationAndId(dbSession, organization, id); + return wsSupport.getByOrganizationAndId(dbSession, organization, id); } throw new IllegalArgumentException("No parameter has been set to identify a quality gate"); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentAction.java b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentAction.java index 76c55684e0b..c8964af2459 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentAction.java @@ -50,6 +50,7 @@ import org.sonar.db.property.PropertyDto; import org.sonar.db.property.PropertyQuery; import org.sonar.db.qualitygate.QualityGateDto; import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.BillingValidations; import org.sonar.server.organization.BillingValidationsProxy; import org.sonar.server.project.Visibility; @@ -59,6 +60,7 @@ import org.sonar.server.qualityprofile.QualityProfile; import org.sonar.server.ui.PageRepository; import org.sonar.server.user.UserSession; +import static java.lang.String.format; import static org.sonar.api.measures.CoreMetrics.QUALITY_PROFILES_KEY; import static org.sonar.api.utils.DateUtils.formatDateTime; import static org.sonar.api.web.UserRole.ADMIN; @@ -221,7 +223,8 @@ public class ComponentAction implements NavigationWsAction { } private void writeQualityGate(JsonWriter json, DbSession session, OrganizationDto organization, ComponentDto component) { - QualityGateFinder.QualityGateData qualityGateData = qualityGateFinder.getQualityGate(session, organization, component); + QualityGateFinder.QualityGateData qualityGateData = qualityGateFinder.getQualityGate(session, organization, component) + .orElseThrow(() -> new NotFoundException(format("Quality Gate not found for %s", component.getKey()))); QualityGateDto qualityGateDto = qualityGateData.getQualityGate(); json.name("qualityGate").beginObject() .prop("key", qualityGateDto.getId()) diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ConditionEvaluatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ConditionEvaluatorTest.java deleted file mode 100644 index 8f73faf337c..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ConditionEvaluatorTest.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 java.util.Optional; -import java.util.OptionalDouble; -import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.measures.Metric; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.qualitygate.ConditionEvaluatorTest.FakeMeasure.newFakeMeasureOnLeak; - -public class ConditionEvaluatorTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void EQUALS_double() { - test(new FakeMeasure(10.1d), Condition.Operator.EQUALS, "10.2", EvaluatedCondition.EvaluationStatus.OK, "10.1"); - test(new FakeMeasure(10.2d), Condition.Operator.EQUALS, "10.2", EvaluatedCondition.EvaluationStatus.ERROR, "10.2"); - test(new FakeMeasure(10.3d), Condition.Operator.EQUALS, "10.2", EvaluatedCondition.EvaluationStatus.OK, "10.3"); - } - - @Test - public void NOT_EQUALS_double() { - test(new FakeMeasure(10.1d), Condition.Operator.NOT_EQUALS, "10.2", EvaluatedCondition.EvaluationStatus.ERROR, "10.1"); - test(new FakeMeasure(10.2d), Condition.Operator.NOT_EQUALS, "10.2", EvaluatedCondition.EvaluationStatus.OK, "10.2"); - test(new FakeMeasure(10.3d), Condition.Operator.NOT_EQUALS, "10.2", EvaluatedCondition.EvaluationStatus.ERROR, "10.3"); - } - - @Test - public void GREATER_THAN_double() { - test(new FakeMeasure(10.1d), Condition.Operator.GREATER_THAN, "10.2", EvaluatedCondition.EvaluationStatus.OK, "10.1"); - test(new FakeMeasure(10.2d), Condition.Operator.GREATER_THAN, "10.2", EvaluatedCondition.EvaluationStatus.OK, "10.2"); - test(new FakeMeasure(10.3d), Condition.Operator.GREATER_THAN, "10.2", EvaluatedCondition.EvaluationStatus.ERROR, "10.3"); - } - - @Test - public void LESS_THAN_double() { - test(new FakeMeasure(10.1d), Condition.Operator.LESS_THAN, "10.2", EvaluatedCondition.EvaluationStatus.ERROR, "10.1"); - test(new FakeMeasure(10.2d), Condition.Operator.LESS_THAN, "10.2", EvaluatedCondition.EvaluationStatus.OK, "10.2"); - test(new FakeMeasure(10.3d), Condition.Operator.LESS_THAN, "10.2", EvaluatedCondition.EvaluationStatus.OK, "10.3"); - } - - @Test - public void EQUALS_int() { - test(new FakeMeasure(10), Condition.Operator.EQUALS, "9", EvaluatedCondition.EvaluationStatus.OK, "10"); - test(new FakeMeasure(10), Condition.Operator.EQUALS, "10", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - test(new FakeMeasure(10), Condition.Operator.EQUALS, "11", EvaluatedCondition.EvaluationStatus.OK, "10"); - - // badly stored thresholds are truncated - test(new FakeMeasure(10), Condition.Operator.EQUALS, "10.4", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - test(new FakeMeasure(10), Condition.Operator.EQUALS, "10.9", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - test(new FakeMeasure(11), Condition.Operator.EQUALS, "10.9", EvaluatedCondition.EvaluationStatus.OK, "11"); - } - - @Test - public void NOT_EQUALS_int() { - test(new FakeMeasure(10), Condition.Operator.NOT_EQUALS, "9", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - test(new FakeMeasure(10), Condition.Operator.NOT_EQUALS, "10", EvaluatedCondition.EvaluationStatus.OK, "10"); - test(new FakeMeasure(10), Condition.Operator.NOT_EQUALS, "11", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - - // badly stored thresholds are truncated - test(new FakeMeasure(10), Condition.Operator.NOT_EQUALS, "10.4", EvaluatedCondition.EvaluationStatus.OK, "10"); - test(new FakeMeasure(10), Condition.Operator.NOT_EQUALS, "10.9", EvaluatedCondition.EvaluationStatus.OK, "10"); - test(new FakeMeasure(10), Condition.Operator.NOT_EQUALS, "9.9", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - } - - @Test - public void GREATER_THAN_int() { - test(new FakeMeasure(10), Condition.Operator.GREATER_THAN, "9", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - test(new FakeMeasure(10), Condition.Operator.GREATER_THAN, "10", EvaluatedCondition.EvaluationStatus.OK, "10"); - test(new FakeMeasure(10), Condition.Operator.GREATER_THAN, "11", EvaluatedCondition.EvaluationStatus.OK, "10"); - - testOnLeak(newFakeMeasureOnLeak(10), Condition.Operator.GREATER_THAN, "9", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - testOnLeak(newFakeMeasureOnLeak(10), Condition.Operator.GREATER_THAN, "10", EvaluatedCondition.EvaluationStatus.OK, "10"); - testOnLeak(newFakeMeasureOnLeak(10), Condition.Operator.GREATER_THAN, "11", EvaluatedCondition.EvaluationStatus.OK, "10"); - } - - @Test - public void LESS_THAN_int() { - test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "9", EvaluatedCondition.EvaluationStatus.OK, "10"); - test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "10", EvaluatedCondition.EvaluationStatus.OK, "10"); - test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "11", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "11", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - - testOnLeak(newFakeMeasureOnLeak(10), Condition.Operator.LESS_THAN, "9", EvaluatedCondition.EvaluationStatus.OK, "10"); - testOnLeak(newFakeMeasureOnLeak(10), Condition.Operator.LESS_THAN, "10", EvaluatedCondition.EvaluationStatus.OK, "10"); - testOnLeak(newFakeMeasureOnLeak(10), Condition.Operator.LESS_THAN, "11", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - testOnLeak(newFakeMeasureOnLeak(10), Condition.Operator.LESS_THAN, "11", EvaluatedCondition.EvaluationStatus.ERROR, "10"); - } - - @Test - public void no_value_present() { - test(new FakeMeasure((Integer) null), Condition.Operator.LESS_THAN, "9", EvaluatedCondition.EvaluationStatus.OK, null); - test(null, Condition.Operator.LESS_THAN, "9", EvaluatedCondition.EvaluationStatus.OK, null); - } - - @Test - public void empty_warning_condition() { - test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "9", null, EvaluatedCondition.EvaluationStatus.OK, "10"); - test(new FakeMeasure(10), Condition.Operator.LESS_THAN, "9", "", EvaluatedCondition.EvaluationStatus.OK, "10"); - test(new FakeMeasure(3), Condition.Operator.LESS_THAN, "9", "", EvaluatedCondition.EvaluationStatus.ERROR, "3"); - } - - private void test(@Nullable QualityGateEvaluator.Measure measure, Condition.Operator operator, String errorThreshold, EvaluatedCondition.EvaluationStatus expectedStatus, - @Nullable String expectedValue) { - test(measure, operator, errorThreshold, null, expectedStatus, expectedValue); - } - - 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); - - EvaluatedCondition result = ConditionEvaluator.evaluate(condition, new FakeMeasures(measure)); - - assertThat(result.getStatus()).isEqualTo(expectedStatus); - if (expectedValue == null) { - assertThat(result.getValue()).isNotPresent(); - } else { - assertThat(result.getValue()).hasValue(expectedValue); - } - } - - 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); - - EvaluatedCondition result = ConditionEvaluator.evaluate(condition, new FakeMeasures(measure)); - - assertThat(result.getStatus()).isEqualTo(expectedStatus); - if (expectedValue == null) { - assertThat(result.getValue()).isNotPresent(); - } else { - assertThat(result.getValue()).hasValue(expectedValue); - } - } - - private static class FakeMeasures implements QualityGateEvaluator.Measures { - private final QualityGateEvaluator.Measure measure; - - FakeMeasures(@Nullable QualityGateEvaluator.Measure measure) { - this.measure = measure; - } - - @Override - public Optional<QualityGateEvaluator.Measure> get(String metricKey) { - return Optional.ofNullable(measure); - } - } - - static class FakeMeasure implements QualityGateEvaluator.Measure { - private Double leakValue; - private Double value; - private Metric.ValueType valueType; - - private FakeMeasure() { - - } - - FakeMeasure(@Nullable Double value) { - this.value = value; - this.valueType = Metric.ValueType.FLOAT; - } - - FakeMeasure(@Nullable Integer value) { - this.value = value == null ? null : value.doubleValue(); - this.valueType = Metric.ValueType.INT; - } - - static FakeMeasure newFakeMeasureOnLeak(@Nullable Integer value) { - FakeMeasure that = new FakeMeasure(); - that.leakValue = value == null ? null : value.doubleValue(); - that.valueType = Metric.ValueType.INT; - return that; - } - - @Override - public Metric.ValueType getType() { - return valueType; - } - - @Override - public OptionalDouble getValue() { - return value == null ? OptionalDouble.empty() : OptionalDouble.of(value); - } - - @Override - public Optional<String> getStringValue() { - return Optional.empty(); - } - - @Override - public OptionalDouble getLeakValue() { - return leakValue == null ? OptionalDouble.empty() : OptionalDouble.of(leakValue); - } - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateFinderTest.java deleted file mode 100644 index fc05daf97d4..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateFinderTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.exceptions.NotFoundException; - -import static java.lang.String.format; -import static org.assertj.core.api.Assertions.assertThat; - -public class QualityGateFinderTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - - private DbSession dbSession = db.getSession(); - - private QualityGateFinder underTest = new QualityGateFinder(db.getDbClient()); - - @Test - public void return_default_quality_gate_for_project() { - ComponentDto project = db.components().insertPrivateProject(); - QualityGateDto dbQualityGate = db.qualityGates().createDefaultQualityGate(db.getDefaultOrganization(), qg -> qg.setName("Sonar way")); - - QualityGateFinder.QualityGateData result = underTest.getQualityGate(dbSession, db.getDefaultOrganization(), project); - - assertThat(result).isNotNull(); - assertThat(result.getQualityGate().getId()).isEqualTo(dbQualityGate.getId()); - assertThat(result.isDefault()).isTrue(); - } - - @Test - public void return_project_quality_gate_over_default() { - ComponentDto project = db.components().insertPrivateProject(); - db.qualityGates().createDefaultQualityGate(db.getDefaultOrganization(),qg -> qg.setName("Sonar way")); - QualityGateDto dbQualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization(), qg -> qg.setName("My team QG")); - db.qualityGates().associateProjectToQualityGate(project, dbQualityGate); - - QualityGateFinder.QualityGateData result = underTest.getQualityGate(dbSession, db.getDefaultOrganization(), project); - - assertThat(result).isNotNull(); - assertThat(result.getQualityGate().getId()).isEqualTo(dbQualityGate.getId()); - assertThat(result.isDefault()).isFalse(); - } - - @Test - public void fail_when_default_qgate_defined_does_not_exists() { - ComponentDto project = db.components().insertPrivateProject(); - QualityGateDto dbQualityGate = db.qualityGates().createDefaultQualityGate(db.getDefaultOrganization(), qg -> qg.setName("Sonar way")); - db.getDbClient().qualityGateDao().delete(dbQualityGate, dbSession); - db.commit(); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage(format("Unable to find the quality gate [%s] for organization [%s]", dbQualityGate.getUuid(), db.getDefaultOrganization().getUuid())); - - underTest.getQualityGate(dbSession, db.getDefaultOrganization(), project); - } - - @Test - public void fail_when_project_qgate_defined_does_not_exists() { - ComponentDto project = db.components().insertPrivateProject(); - QualityGateDto dbQualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization(), qg -> qg.setName("My team QG")); - db.qualityGates().associateProjectToQualityGate(project, dbQualityGate); - db.getDbClient().qualityGateDao().delete(dbQualityGate, dbSession); - - expectedException.expect(NotFoundException.class); - underTest.getQualityGate(dbSession, db.getDefaultOrganization(), project); - } - - @Test - public void fail_when_default_quality_gate_does_not_exists() { - QualityGateDto dbQualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization(), qg -> qg.setName("My team QG")); - db.qualityGates().setDefaultQualityGate(db.getDefaultOrganization(), dbQualityGate); - db.getDbClient().qualityGateDao().delete(dbQualityGate, dbSession); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage(format("Default quality gate [%s] is missing on organization [%s]", dbQualityGate.getUuid(), db.getDefaultOrganization().getUuid())); - - underTest.getDefault(dbSession, db.getDefaultOrganization()); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CopyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CopyActionTest.java index cdf8ca1bdb2..15e3f0aaedd 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CopyActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CopyActionTest.java @@ -36,7 +36,6 @@ import org.sonar.db.qualitygate.QualityGateDto; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.qualitygate.QualityGateUpdater; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; @@ -66,10 +65,9 @@ public class CopyActionTest { private DbSession dbSession = db.getSession(); private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); private QualityGateUpdater qualityGateUpdater = new QualityGateUpdater(dbClient, UuidFactoryFast.getInstance()); - private QualityGateFinder qualityGateFinder = new QualityGateFinder(dbClient); private QualityGatesWsSupport wsSupport = new QualityGatesWsSupport(dbClient, userSession, defaultOrganizationProvider); - private CopyAction underTest = new CopyAction(dbClient, userSession, qualityGateUpdater, qualityGateFinder, wsSupport); + private CopyAction underTest = new CopyAction(dbClient, userSession, qualityGateUpdater, wsSupport); private WsActionTester ws = new WsActionTester(underTest); @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateConditionActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateConditionActionTest.java index 01f3bc60e20..f84312e1fb3 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateConditionActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateConditionActionTest.java @@ -36,7 +36,6 @@ import org.sonar.db.qualitygate.QualityGateDto; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.qualitygate.QualityGateConditionsUpdater; -import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Qualitygates.CreateConditionResponse; @@ -69,7 +68,7 @@ public class CreateConditionActionTest { private DbClient dbClient = db.getDbClient(); private DbSession dbSession = db.getSession(); private CreateConditionAction underTest = new CreateConditionAction(dbClient, new QualityGateConditionsUpdater(dbClient), - new QualityGateFinder(dbClient), new QualityGatesWsSupport(dbClient, userSession, defaultOrganizationProvider)); + new QualityGatesWsSupport(dbClient, userSession, defaultOrganizationProvider)); private WsActionTester ws = new WsActionTester(underTest); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/RenameActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/RenameActionTest.java index 04126263575..e90ff463653 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/RenameActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/RenameActionTest.java @@ -31,7 +31,6 @@ import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Qualitygates.QualityGate; @@ -54,7 +53,7 @@ public class RenameActionTest { private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); private WsActionTester ws = new WsActionTester( - new RenameAction(db.getDbClient(), new QualityGateFinder(db.getDbClient()), new QualityGatesWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider))); + new RenameAction(db.getDbClient(), new QualityGatesWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider))); @Test public void verify_definition() { diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SearchActionTest.java index 72983d3761f..ab581808b24 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SearchActionTest.java @@ -31,7 +31,6 @@ import org.sonar.db.qualitygate.QualityGateDto; import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Qualitygates.SearchResponse; @@ -66,7 +65,7 @@ public class SearchActionTest { private DbClient dbClient = db.getDbClient(); private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); - private SearchAction underTest = new SearchAction(dbClient, userSession, new QualityGateFinder(dbClient), + private SearchAction underTest = new SearchAction(dbClient, userSession, new QualityGatesWsSupport(dbClient, userSession, defaultOrganizationProvider)); private WsActionTester ws = new WsActionTester(underTest); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SelectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SelectActionTest.java index 0b27f7c606f..063a57487be 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SelectActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SelectActionTest.java @@ -33,7 +33,6 @@ import org.sonar.server.component.TestComponentFinder; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; @@ -55,8 +54,7 @@ public class SelectActionTest { private DbClient dbClient = db.getDbClient(); private SelectAction underTest = new SelectAction(dbClient, TestComponentFinder.from(db), - new QualityGatesWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db)), - new QualityGateFinder(db.getDbClient())); + new QualityGatesWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db))); private WsActionTester ws = new WsActionTester(underTest); @Test |