aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2015-06-08 16:56:11 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2015-06-11 10:28:34 +0200
commit3867d47f87b70dd4aaab4a390485675a3672e5a3 (patch)
tree52afc86ac31de3bad8287e79e749795790d2b091
parent6abce5190a0a399f0b7e0af09cda6e86b2188284 (diff)
downloadsonarqube-3867d47f87b70dd4aaab4a390485675a3672e5a3.tar.gz
sonarqube-3867d47f87b70dd4aaab4a390485675a3672e5a3.zip
SONAR-6620 add step to retrieve project's QualityGate
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/Condition.java103
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/MutableQualityGateHolder.java36
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGate.java46
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateHolder.java31
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateHolderImpl.java47
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateService.java29
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateServiceImpl.java67
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/package-info.java24
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityGateLoadingStep.java97
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/ConditionTest.java67
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/MutableQualityGateHolderRule.java53
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/QualityGateHolderImplTest.java58
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/QualityGateServiceImplTest.java88
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/QualityGateLoadingStepTest.java117
16 files changed, 870 insertions, 0 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java
index f3386a42786..959f20b081b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java
@@ -53,6 +53,8 @@ import org.sonar.server.computation.measure.MeasureRepositoryImpl;
import org.sonar.server.computation.measure.MetricCache;
import org.sonar.server.computation.metric.MetricRepositoryImpl;
import org.sonar.server.computation.period.PeriodsHolderImpl;
+import org.sonar.server.computation.qualitygate.QualityGateHolderImpl;
+import org.sonar.server.computation.qualitygate.QualityGateServiceImpl;
import org.sonar.server.computation.step.ComputationStep;
import org.sonar.server.computation.step.ComputationSteps;
import org.sonar.server.view.index.ViewIndex;
@@ -128,6 +130,7 @@ public class ComputeEngineContainerImpl extends ComponentContainer implements Co
BatchReportDirectoryHolderImpl.class,
TreeRootHolderImpl.class,
PeriodsHolderImpl.class,
+ QualityGateHolderImpl.class,
BatchReportReaderImpl.class,
@@ -139,6 +142,8 @@ public class ComputeEngineContainerImpl extends ComponentContainer implements Co
ProjectSettingsRepository.class,
DbIdsRepository.class,
+ QualityGateServiceImpl.class,
+
// issues
ScmAccountCacheLoader.class,
ScmAccountCache.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/Condition.java b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/Condition.java
new file mode 100644
index 00000000000..7e18390fb5a
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/Condition.java
@@ -0,0 +1,103 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import com.google.common.base.Objects;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.server.computation.metric.Metric;
+
+import static java.util.Objects.hash;
+import static java.util.Objects.requireNonNull;
+
+@Immutable
+public class Condition {
+
+ private final Metric metric;
+ @CheckForNull
+ private final Integer period;
+ private final String operator;
+ @CheckForNull
+ private final String warningThreshold;
+ @CheckForNull
+ private final String errorThreshold;
+
+ public Condition(Metric metric, @Nullable Integer period,
+ String operator, @Nullable String errorThreshold, @Nullable String warningThreshold) {
+ this.metric = requireNonNull(metric);
+ this.operator = requireNonNull(operator);
+ this.period = period;
+ this.errorThreshold = errorThreshold;
+ this.warningThreshold = warningThreshold;
+ }
+
+ public Metric getMetric() {
+ return metric;
+ }
+
+ @CheckForNull
+ public Integer getPeriod() {
+ return period;
+ }
+
+ public String getOperator() {
+ return operator;
+ }
+
+ @CheckForNull
+ public String getWarningThreshold() {
+ return warningThreshold;
+ }
+
+ @CheckForNull
+ public String getErrorThreshold() {
+ return errorThreshold;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Condition that = (Condition) o;
+ return java.util.Objects.equals(metric, that.metric)
+ && java.util.Objects.equals(period, that.period);
+ }
+
+ @Override
+ public int hashCode() {
+ return hash(metric, period);
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .add("metric", metric)
+ .add("period", period)
+ .add("operator", operator)
+ .add("warningThreshold", warningThreshold)
+ .add("errorThreshold", errorThreshold)
+ .toString();
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/MutableQualityGateHolder.java b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/MutableQualityGateHolder.java
new file mode 100644
index 00000000000..e977bfc7c29
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/MutableQualityGateHolder.java
@@ -0,0 +1,36 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import org.sonar.server.computation.ReportQueue;
+import org.sonar.server.computation.component.Component;
+
+public interface MutableQualityGateHolder extends QualityGateHolder {
+ /**
+ * Sets the quality gate for the project of the currently processed {@link ReportQueue.Item}.
+ * Settings a quality gate more than once is not allowed and it can never be set to {@code null}.
+ *
+ * @param qualityGate a {@link Component}, can not be {@code null}
+ *
+ * @throws NullPointerException if {@code qualityGate} is {@code null}
+ * @throws IllegalStateException if the quality gate has already been set
+ */
+ void setQualityGate(QualityGate qualityGate);
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGate.java b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGate.java
new file mode 100644
index 00000000000..5978b1069c9
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGate.java
@@ -0,0 +1,46 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import java.util.Objects;
+import java.util.Set;
+import javax.annotation.concurrent.Immutable;
+
+import static com.google.common.base.Predicates.notNull;
+import static com.google.common.collect.FluentIterable.from;
+
+@Immutable
+public class QualityGate {
+ private final String name;
+ private final Set<Condition> conditions;
+
+ public QualityGate(String name, Iterable<Condition> conditions) {
+ this.name = Objects.requireNonNull(name);
+ this.conditions = from(conditions).filter(notNull()).toSet();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Set<Condition> getConditions() {
+ return conditions;
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateHolder.java b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateHolder.java
new file mode 100644
index 00000000000..bba76845499
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateHolder.java
@@ -0,0 +1,31 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import org.sonar.server.computation.ReportQueue;
+
+public interface QualityGateHolder {
+ /**
+ * The QualityGate for the project of the current {@link ReportQueue.Item}.
+ *
+ * @throws IllegalStateException if the holder is empty (ie. there is no quality gate yet)
+ */
+ QualityGate getQualityGate();
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateHolderImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateHolderImpl.java
new file mode 100644
index 00000000000..707c7d7aea1
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateHolderImpl.java
@@ -0,0 +1,47 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import java.util.Objects;
+import javax.annotation.CheckForNull;
+
+public class QualityGateHolderImpl implements MutableQualityGateHolder {
+ @CheckForNull
+ private QualityGate qualityGate;
+
+ @Override
+ public void setQualityGate(QualityGate qualityGate) {
+ // fail fast
+ Objects.requireNonNull(qualityGate);
+
+ if (this.qualityGate != null) {
+ throw new IllegalStateException("QualityGate can be set only once");
+ }
+ this.qualityGate = qualityGate;
+ }
+
+ @Override
+ public QualityGate getQualityGate() {
+ if (qualityGate == null) {
+ throw new IllegalStateException("QualityGate has not been set yet");
+ }
+ return qualityGate;
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateService.java b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateService.java
new file mode 100644
index 00000000000..e722eedc038
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateService.java
@@ -0,0 +1,29 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import com.google.common.base.Optional;
+
+public interface QualityGateService {
+ /**
+ * Retrieve the {@link QualityGate} from the database with the specified id, it it exists.
+ */
+ Optional<QualityGate> findById(long id);
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateServiceImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateServiceImpl.java
new file mode 100644
index 00000000000..2f3d3ef0168
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateServiceImpl.java
@@ -0,0 +1,67 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import javax.annotation.Nonnull;
+import org.sonar.core.qualitygate.db.QualityGateConditionDao;
+import org.sonar.core.qualitygate.db.QualityGateConditionDto;
+import org.sonar.core.qualitygate.db.QualityGateDao;
+import org.sonar.core.qualitygate.db.QualityGateDto;
+import org.sonar.server.computation.metric.Metric;
+import org.sonar.server.computation.metric.MetricRepository;
+
+import static com.google.common.collect.FluentIterable.from;
+
+public class QualityGateServiceImpl implements QualityGateService {
+ private final QualityGateDao qualityGateDao;
+ private final QualityGateConditionDao conditionDao;
+ private final Function<QualityGateConditionDto, Condition> conditionDtoToBean;
+
+ public QualityGateServiceImpl(QualityGateDao qualityGateDao, QualityGateConditionDao conditionDao, final MetricRepository metricRepository) {
+ this.qualityGateDao = qualityGateDao;
+ this.conditionDao = conditionDao;
+ this.conditionDtoToBean = new Function<QualityGateConditionDto, Condition>() {
+ @Override
+ @Nonnull
+ public Condition apply(@Nonnull QualityGateConditionDto input) {
+ Metric metric = metricRepository.getByKey(input.getMetricKey());
+ return new Condition(metric, input.getPeriod(), input.getOperator(), input.getErrorThreshold(), input.getWarningThreshold());
+ }
+ };
+ }
+
+ @Override
+ public Optional<QualityGate> findById(long id) {
+ QualityGateDto qualityGateDto = qualityGateDao.selectById(id);
+ if (qualityGateDto == null) {
+ return Optional.absent();
+ }
+ return Optional.of(toQualityGate(qualityGateDto));
+ }
+
+ private QualityGate toQualityGate(QualityGateDto qualityGateDto) {
+ Iterable<Condition> conditions = from(conditionDao.selectForQualityGate(qualityGateDto.getId())).transform(conditionDtoToBean);
+
+ return new QualityGate(qualityGateDto.getName(), conditions);
+ }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/package-info.java
new file mode 100644
index 00000000000..bdef32c3b7e
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.server.computation.qualitygate;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java
index 57396619bdb..2d13c1a1529 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java
@@ -47,6 +47,8 @@ public class ComputationSteps {
// Read report
ParseReportStep.class,
+ QualityGateLoadingStep.class,
+
// data computation
QualityProfileEventsStep.class,
QualityGateEventsStep.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityGateLoadingStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityGateLoadingStep.java
new file mode 100644
index 00000000000..3bfb04aa958
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityGateLoadingStep.java
@@ -0,0 +1,97 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.step;
+
+import java.util.Collections;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.config.Settings;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.server.computation.ReportQueue;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
+import org.sonar.server.computation.component.ProjectSettingsRepository;
+import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.computation.qualitygate.Condition;
+import org.sonar.server.computation.qualitygate.MutableQualityGateHolder;
+import org.sonar.server.computation.qualitygate.QualityGate;
+import org.sonar.server.computation.qualitygate.QualityGateService;
+
+import static org.sonar.server.computation.component.Component.Type.PROJECT;
+import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;
+
+/**
+ * This step retrieves the QualityGate for the current {@link ReportQueue.Item} and stores it in
+ * {@link MutableQualityGateHolder}.
+ */
+public class QualityGateLoadingStep implements ComputationStep {
+ private static final Logger LOGGER = Loggers.get(QualityGateLoadingStep.class);
+
+ private static final String PROPERTY_QUALITY_GATE = "sonar.qualitygate";
+ private static final QualityGate DEFAULT_QUALITY_GATE = new QualityGate("default Quality Gate", Collections.<Condition>emptyList());
+
+ private final TreeRootHolder treeRootHolder;
+ private final ProjectSettingsRepository projectSettingsRepository;
+ private final QualityGateService qualityGateService;
+ private final MutableQualityGateHolder qualityGateHolder;
+
+ public QualityGateLoadingStep(TreeRootHolder treeRootHolder, ProjectSettingsRepository projectSettingsRepository,
+ QualityGateService qualityGateService, MutableQualityGateHolder qualityGateHolder) {
+ this.treeRootHolder = treeRootHolder;
+ this.projectSettingsRepository = projectSettingsRepository;
+ this.qualityGateService = qualityGateService;
+ this.qualityGateHolder = qualityGateHolder;
+ }
+
+ @Override
+ public void execute() {
+ new DepthTraversalTypeAwareVisitor(PROJECT, PRE_ORDER) {
+ @Override
+ public void visitProject(Component project) {
+ executeForProject(project);
+ }
+ }.visit(treeRootHolder.getRoot());
+ }
+
+ private void executeForProject(Component project) {
+ String projectKey = project.getKey();
+ Settings settings = projectSettingsRepository.getProjectSettings(projectKey);
+ String qualityGateSetting = settings.getString(PROPERTY_QUALITY_GATE);
+
+ if (qualityGateSetting == null || StringUtils.isBlank(qualityGateSetting)) {
+ LOGGER.debug("No quality gate is configured for project " + projectKey);
+ qualityGateHolder.setQualityGate(DEFAULT_QUALITY_GATE);
+ return;
+ }
+
+ try {
+ long qualityGateId = Long.valueOf(qualityGateSetting.trim());
+ qualityGateHolder.setQualityGate(qualityGateService.findById(qualityGateId).or(DEFAULT_QUALITY_GATE));
+ } catch (NumberFormatException e) {
+ LOGGER.error(String.format("Unsupported value in property %s, using empty Quality Gate", PROPERTY_QUALITY_GATE));
+ qualityGateHolder.setQualityGate(DEFAULT_QUALITY_GATE);
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Retrieve Quality Gate";
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/ConditionTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/ConditionTest.java
new file mode 100644
index 00000000000..e53d09f3d5a
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/ConditionTest.java
@@ -0,0 +1,67 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import org.junit.Test;
+import org.sonar.server.computation.metric.Metric;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ConditionTest {
+ private static final Metric SOME_METRIC = mock(Metric.class);
+ private static final String SOME_OPERATOR = "ope";
+
+ @Test(expected = NullPointerException.class)
+ public void constructor_throws_NPE_for_null_metric_argument() {
+ new Condition(null, null, SOME_OPERATOR, null, null);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void constructor_throws_NPE_for_null_operator_argument() {
+ new Condition(SOME_METRIC, null, null, null, null);
+ }
+
+ @Test
+ public void verify_getters() {
+ Integer period = 1;
+ String error = "error threshold";
+ String warning = "warning threshold";
+
+ Condition condition = new Condition(SOME_METRIC, period, SOME_OPERATOR, error, warning);
+
+ assertThat(condition.getMetric()).isSameAs(SOME_METRIC);
+ assertThat(condition.getOperator()).isSameAs(SOME_OPERATOR);
+ assertThat(condition.getPeriod()).isEqualTo(period);
+ assertThat(condition.getErrorThreshold()).isEqualTo(error);
+ assertThat(condition.getWarningThreshold()).isEqualTo(warning);
+ }
+
+ @Test
+ public void all_fields_are_displayed_in_toString() {
+ when(SOME_METRIC.toString()).thenReturn("metric1");
+
+ assertThat(new Condition(SOME_METRIC, 1, SOME_OPERATOR, "error_l", "warn").toString())
+ .isEqualTo("Condition{metric=metric1, period=1, operator=ope, warningThreshold=warn, errorThreshold=error_l}");
+
+ }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/MutableQualityGateHolderRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/MutableQualityGateHolderRule.java
new file mode 100644
index 00000000000..22367f7bc43
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/MutableQualityGateHolderRule.java
@@ -0,0 +1,53 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import java.util.Objects;
+import org.junit.rules.ExternalResource;
+
+public class MutableQualityGateHolderRule extends ExternalResource implements MutableQualityGateHolder {
+ private QualityGate qualityGate;
+
+ @Override
+ public void setQualityGate(QualityGate qualityGate) {
+ Objects.requireNonNull(qualityGate);
+ if (this.qualityGate != null) {
+ throw new IllegalStateException("QualityGate can not be set more than once");
+ }
+ this.qualityGate = qualityGate;
+ }
+
+ @Override
+ public QualityGate getQualityGate() {
+ if (this.qualityGate == null) {
+ throw new IllegalStateException("QualityGate has not been set");
+ }
+ return qualityGate;
+ }
+
+ @Override
+ protected void after() {
+ reset();
+ }
+
+ public void reset() {
+ this.qualityGate = null;
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/QualityGateHolderImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/QualityGateHolderImplTest.java
new file mode 100644
index 00000000000..64b417bcdd8
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/QualityGateHolderImplTest.java
@@ -0,0 +1,58 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import java.util.Collections;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class QualityGateHolderImplTest {
+
+ public static final QualityGate QUALITY_GATE = new QualityGate("name", Collections.<Condition>emptyList());
+
+ @Test(expected = IllegalStateException.class)
+ public void getQualityGate_throws_ISE_if_QualityGate_not_set() {
+ new QualityGateHolderImpl().getQualityGate();
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void setQualityGate_throws_NPE_if_argument_is_null() {
+ new QualityGateHolderImpl().setQualityGate(null);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void setQualityGate_throws_ISE_if_called_twice() {
+ QualityGateHolderImpl holder = new QualityGateHolderImpl();
+
+ holder.setQualityGate(QUALITY_GATE);
+ holder.setQualityGate(QUALITY_GATE);
+ }
+
+ @Test
+ public void getQualityGate_returns_QualityGate_set_by_setQualityGate() {
+ QualityGateHolderImpl holder = new QualityGateHolderImpl();
+
+ holder.setQualityGate(QUALITY_GATE);
+
+ assertThat(holder.getQualityGate()).isSameAs(QUALITY_GATE);
+ }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/QualityGateServiceImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/QualityGateServiceImplTest.java
new file mode 100644
index 00000000000..dfb6bd3b843
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/QualityGateServiceImplTest.java
@@ -0,0 +1,88 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.qualitygate;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import java.util.Collections;
+import org.junit.Test;
+import org.sonar.core.qualitygate.db.QualityGateConditionDao;
+import org.sonar.core.qualitygate.db.QualityGateConditionDto;
+import org.sonar.core.qualitygate.db.QualityGateDao;
+import org.sonar.core.qualitygate.db.QualityGateDto;
+import org.sonar.server.computation.metric.Metric;
+import org.sonar.server.computation.metric.MetricRepository;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.guava.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class QualityGateServiceImplTest {
+ private static final long SOME_ID = 123;
+ private static final String SOME_NAME = "some name";
+ private static final QualityGateDto QUALITY_GATE_DTO = new QualityGateDto().setId(SOME_ID).setName(SOME_NAME);
+ private static final String METRIC_KEY_1 = "metric_key_1";
+ private static final String METRIC_KEY_2 = "metric_key_2";
+ 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).setMetricKey(METRIC_KEY_1).setOperator("=").setPeriod(1).setWarningThreshold("warnin_th").setErrorThreshold("error_th");
+ private static final QualityGateConditionDto CONDITION_2 = new QualityGateConditionDto().setId(456).setMetricKey(METRIC_KEY_2).setOperator("=");
+
+ private QualityGateDao qualityGateDao = mock(QualityGateDao.class);
+ private QualityGateConditionDao qualityGateConditionDao = mock(QualityGateConditionDao.class);
+ private MetricRepository metricRepository = mock(MetricRepository.class);
+ private QualityGateServiceImpl underTest = new QualityGateServiceImpl(qualityGateDao, qualityGateConditionDao, metricRepository);
+
+ @Test
+ public void findById_returns_absent_when_QualityGateDto_does_not_exist() {
+ assertThat(underTest.findById(SOME_ID)).isAbsent();
+ }
+
+ @Test
+ public void findById_returns_QualityGate_with_empty_set_of_conditions_when_there_is_none_in_DB() {
+ when(qualityGateDao.selectById(SOME_ID)).thenReturn(QUALITY_GATE_DTO);
+ when(qualityGateConditionDao.selectForQualityGate(SOME_ID)).thenReturn(Collections.<QualityGateConditionDto>emptyList());
+
+ Optional<QualityGate> res = underTest.findById(SOME_ID);
+
+ assertThat(res).isPresent();
+ assertThat(res.get().getName()).isEqualTo(SOME_NAME);
+ assertThat(res.get().getConditions()).isEmpty();
+ }
+
+ @Test
+ public void findById_returns_conditions_when_there_is_some_in_DB() {
+ when(qualityGateDao.selectById(SOME_ID)).thenReturn(QUALITY_GATE_DTO);
+ when(qualityGateConditionDao.selectForQualityGate(SOME_ID)).thenReturn(ImmutableList.of(CONDITION_1, CONDITION_2));
+ // metrics are always supposed to be there
+ when(metricRepository.getByKey(METRIC_KEY_1)).thenReturn(METRIC_1);
+ when(metricRepository.getByKey(METRIC_KEY_2)).thenReturn(METRIC_2);
+
+ Optional<QualityGate> res = underTest.findById(SOME_ID);
+
+ assertThat(res).isPresent();
+ assertThat(res.get().getName()).isEqualTo(SOME_NAME);
+ assertThat(res.get().getConditions()).containsOnly(
+ new Condition(METRIC_1, CONDITION_1.getPeriod(), CONDITION_1.getOperator(), CONDITION_1.getErrorThreshold(), CONDITION_1.getWarningThreshold()),
+ new Condition(METRIC_2, CONDITION_2.getPeriod(), CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold(), CONDITION_2.getWarningThreshold())
+ );
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/QualityGateLoadingStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/QualityGateLoadingStepTest.java
new file mode 100644
index 00000000000..ee4b3256062
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/QualityGateLoadingStepTest.java
@@ -0,0 +1,117 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.step;
+
+import com.google.common.base.Optional;
+import java.util.Collections;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DumbComponent;
+import org.sonar.server.computation.component.ProjectSettingsRepository;
+import org.sonar.server.computation.qualitygate.Condition;
+import org.sonar.server.computation.qualitygate.MutableQualityGateHolderRule;
+import org.sonar.server.computation.qualitygate.QualityGate;
+import org.sonar.server.computation.qualitygate.QualityGateService;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class QualityGateLoadingStepTest {
+ private static final String PROJECT_KEY = "project key";
+ public static final DumbComponent PROJECT_ALONE = DumbComponent.builder(Component.Type.PROJECT, 1).setKey(PROJECT_KEY).build();
+
+ @Rule
+ public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+ @Rule
+ public MutableQualityGateHolderRule mutableQualityGateHolder = new MutableQualityGateHolderRule();
+
+ private ProjectSettingsRepository projectSettingsRepository = mock(ProjectSettingsRepository.class);
+ private QualityGateService qualityGateService = mock(QualityGateService.class);
+
+ private QualityGateLoadingStep underTest = new QualityGateLoadingStep(treeRootHolder, projectSettingsRepository, qualityGateService, mutableQualityGateHolder);
+
+ @Test
+ public void execute_sets_default_QualityGate_when_project_has_no_settings() {
+ treeRootHolder.setRoot(DumbComponent.builder(Component.Type.PROJECT, 1).setKey(PROJECT_KEY).addChildren(DumbComponent.builder(Component.Type.FILE, 2).build()).build());
+ when(projectSettingsRepository.getProjectSettings(PROJECT_KEY)).thenReturn(new Settings());
+
+ underTest.execute();
+
+ verifyDefaultQualityGateHasBeenSet();
+
+ // verify only project is processed
+ verify(projectSettingsRepository).getProjectSettings(PROJECT_KEY);
+ verifyNoMoreInteractions(projectSettingsRepository);
+ }
+
+ @Test
+ public void execute_sets_default_QualityGate_when_property_value_is_not_a_long() {
+ verify_execute_sets_default_QualityGate_when_property_value_is_not_a_long("");
+ verify_execute_sets_default_QualityGate_when_property_value_is_not_a_long(" ");
+ verify_execute_sets_default_QualityGate_when_property_value_is_not_a_long(" 10 sds ");
+ }
+
+ private void verify_execute_sets_default_QualityGate_when_property_value_is_not_a_long(String value) {
+ treeRootHolder.setRoot(PROJECT_ALONE);
+ when(projectSettingsRepository.getProjectSettings(PROJECT_KEY)).thenReturn(new Settings().setProperty("sonar.qualitygate", value));
+
+ underTest.execute();
+
+ verifyDefaultQualityGateHasBeenSet();
+
+ mutableQualityGateHolder.reset();
+ }
+
+ @Test
+ public void execute_sets_default_QualityGate_if_it_can_not_be_found_by_service() {
+ treeRootHolder.setRoot(PROJECT_ALONE);
+ when(projectSettingsRepository.getProjectSettings(PROJECT_KEY)).thenReturn(new Settings().setProperty("sonar.qualitygate", 10));
+ when(qualityGateService.findById(10)).thenReturn(Optional.<QualityGate>absent());
+
+ underTest.execute();
+
+ verifyDefaultQualityGateHasBeenSet();
+ }
+
+ @Test
+ public void execute_sets_QualityGate_if_it_can_be_found_by_service() {
+ QualityGate qualityGate = new QualityGate("name", Collections.<Condition>emptyList());
+
+ treeRootHolder.setRoot(PROJECT_ALONE);
+ when(projectSettingsRepository.getProjectSettings(PROJECT_KEY)).thenReturn(new Settings().setProperty("sonar.qualitygate", 10));
+ when(qualityGateService.findById(10)).thenReturn(Optional.of(qualityGate));
+
+ underTest.execute();
+
+ assertThat(mutableQualityGateHolder.getQualityGate()).isSameAs(qualityGate);
+ }
+
+ private void verifyDefaultQualityGateHasBeenSet() {
+ assertThat(mutableQualityGateHolder.getQualityGate().getName()).isEqualTo("default Quality Gate");
+ assertThat(mutableQualityGateHolder.getQualityGate().getConditions()).isEmpty();
+ }
+
+}