diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-09-27 13:56:32 +0200 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-10-17 15:13:58 +0200 |
commit | 1613b1f008e306b4dd218b37e19685ec610c5db4 (patch) | |
tree | 852c8986790d6e92c0110a10679354136ff1176c | |
parent | 603f93907aa9f2811b9ccf7a2f67b4b578e396ea (diff) | |
download | sonarqube-1613b1f008e306b4dd218b37e19685ec610c5db4.tar.gz sonarqube-1613b1f008e306b4dd218b37e19685ec610c5db4.zip |
SONAR-9871 move WebhookPayloadFactory to share it with web
19 files changed, 1097 insertions, 208 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java index 590813d7df7..267a4523e0f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java @@ -117,7 +117,6 @@ import org.sonar.server.computation.task.projectanalysis.source.SourceHashReposi import org.sonar.server.computation.task.projectanalysis.source.SourceLinesRepositoryImpl; import org.sonar.server.computation.task.projectanalysis.step.ReportComputationSteps; import org.sonar.server.computation.task.projectanalysis.step.SmallChangesetQualityGateSpecialCase; -import org.sonar.server.computation.task.projectanalysis.webhook.WebhookPayloadFactoryImpl; import org.sonar.server.computation.task.projectanalysis.webhook.WebhookPostTask; import org.sonar.server.computation.task.step.ComputationStepExecutor; import org.sonar.server.computation.task.step.ComputationSteps; @@ -274,7 +273,6 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop // webhooks WebhookModule.class, - WebhookPayloadFactoryImpl.class, WebhookPostTask.class); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTask.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTask.java index 41de76dc710..f6112804a54 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTask.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTask.java @@ -19,10 +19,18 @@ */ package org.sonar.server.computation.task.projectanalysis.webhook; +import java.util.Date; +import java.util.Optional; +import java.util.stream.Collectors; import org.sonar.api.ce.posttask.PostProjectAnalysisTask; import org.sonar.api.config.Configuration; import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository; +import org.sonar.server.webhook.Branch; +import org.sonar.server.webhook.CeTask; +import org.sonar.server.webhook.Project; +import org.sonar.server.webhook.QualityGate; import org.sonar.server.webhook.WebHooks; +import org.sonar.server.webhook.WebhookPayloadFactory; public class WebhookPostTask implements PostProjectAnalysisTask { @@ -43,7 +51,27 @@ public class WebhookPostTask implements PostProjectAnalysisTask { webHooks.sendProjectAnalysisUpdate( config, new WebHooks.Analysis(analysis.getProject().getUuid(), analysis.getCeTask().getId()), - () -> payloadFactory.create(analysis)); + () -> payloadFactory.create(convert(analysis))); + } + + private static org.sonar.server.webhook.ProjectAnalysis convert(ProjectAnalysis analysis) { + return new org.sonar.server.webhook.ProjectAnalysis( + new CeTask(analysis.getCeTask().getId(), CeTask.Status.valueOf(analysis.getCeTask().getStatus().name())), + new Project(analysis.getProject().getUuid(), analysis.getProject().getKey(), analysis.getProject().getName()), + analysis.getBranch().map(b -> new Branch(b.isMain(), b.getName().orElse(null), Branch.Type.valueOf(b.getType().name()))).orElse(null), + Optional.ofNullable(analysis.getQualityGate()) + .map(qg -> new QualityGate( + qg.getId(), + qg.getName(), + QualityGate.Status.valueOf(qg.getStatus().name()), + qg.getConditions().stream() + .map(c -> new QualityGate.Condition(QualityGate.EvaluationStatus.valueOf(c.getStatus().name()), c.getMetricKey(), QualityGate.Operator.valueOf(c.getOperator().name()), + c.getErrorThreshold(), c.getWarningThreshold(), c.isOnLeakPeriod(), + c.getStatus() == org.sonar.api.ce.posttask.QualityGate.EvaluationStatus.NO_VALUE ? null : c.getValue())) + .collect(Collectors.toSet()))) + .orElse(null), + analysis.getAnalysisDate().map(Date::getTime).orElse(null), + analysis.getScannerContext().getProperties()); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/Branch.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/Branch.java new file mode 100644 index 00000000000..cbb1b6cd053 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/Branch.java @@ -0,0 +1,82 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.webhook; + +import java.util.Objects; +import java.util.Optional; +import javax.annotation.Nullable; + +import static java.util.Objects.requireNonNull; + +public final class Branch { + private final boolean main; + private final String name; + private final Type type; + + public Branch(boolean main, @Nullable String name, Type type) { + this.main = main; + this.name = name; + this.type = requireNonNull(type, "type can't be null"); + } + + public boolean isMain() { + return main; + } + + public Optional<String> getName() { + return Optional.ofNullable(name); + } + + public Type getType() { + return type; + } + + public enum Type { + LONG, SHORT + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Branch branch = (Branch) o; + return main == branch.main && + Objects.equals(name, branch.name) && + type == branch.type; + } + + @Override + public int hashCode() { + return Objects.hash(main, name, type); + } + + @Override + public String toString() { + return "Branch{" + + "main=" + main + + ", name='" + name + '\'' + + ", type=" + type + + '}'; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/CeTask.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/CeTask.java new file mode 100644 index 00000000000..85053978109 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/CeTask.java @@ -0,0 +1,72 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.webhook; + +import java.util.Objects; + +import static java.util.Objects.requireNonNull; + +public final class CeTask { + private final String id; + private final Status status; + + public CeTask(String id, Status status) { + this.id = requireNonNull(id, "id can't be null"); + this.status = requireNonNull(status, "status can't be null"); + } + + public String getId() { + return id; + } + + public Status getStatus() { + return status; + } + + public enum Status { + SUCCESS, FAILED + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CeTask task = (CeTask) o; + return Objects.equals(id, task.id) && + status == task.status; + } + + @Override + public int hashCode() { + return Objects.hash(id, status); + } + + @Override + public String toString() { + return "CeTask{" + + "id='" + id + '\'' + + ", status=" + status + + '}'; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/Project.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/Project.java new file mode 100644 index 00000000000..769f8f9d0b1 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/Project.java @@ -0,0 +1,76 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.webhook; + +import java.util.Objects; + +import static java.util.Objects.requireNonNull; + +public final class Project { + private final String uuid; + private final String key; + private final String name; + + public Project(String uuid, String key, String name) { + this.uuid = requireNonNull(uuid, "uuid can't be null"); + this.key = requireNonNull(key, "key can't be null"); + this.name = requireNonNull(name, "name can't be null"); + } + + public String getUuid() { + return uuid; + } + + public String getKey() { + return key; + } + + public String getName() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Project project = (Project) o; + return Objects.equals(uuid, project.uuid) && + Objects.equals(key, project.key) && + Objects.equals(name, project.name); + } + + @Override + public int hashCode() { + return Objects.hash(uuid, key, name); + } + + @Override + public String toString() { + return "Project{" + + "uuid='" + uuid + '\'' + + ", key='" + key + '\'' + + ", name='" + name + '\'' + + '}'; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/ProjectAnalysis.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/ProjectAnalysis.java new file mode 100644 index 00000000000..7184c57c9f2 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/ProjectAnalysis.java @@ -0,0 +1,106 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.webhook; + +import java.util.Date; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import javax.annotation.Nullable; + +import static com.google.common.collect.ImmutableMap.copyOf; +import static java.util.Objects.requireNonNull; + +public class ProjectAnalysis { + private final CeTask ceTask; + private final Project project; + private final Branch branch; + private final QualityGate qualityGate; + private final Long date; + private final Map<String, String> properties; + + public ProjectAnalysis(CeTask ceTask, Project project, + @Nullable Branch branch, @Nullable QualityGate qualityGate, @Nullable Long date, Map<String, String> properties) { + this.ceTask = requireNonNull(ceTask, "ceTask can't be null"); + this.project = requireNonNull(project, "project can't be null"); + this.branch = branch; + this.qualityGate = qualityGate; + this.date = date; + this.properties = copyOf(requireNonNull(properties, "properties can't be null")); + } + + public CeTask getCeTask() { + return ceTask; + } + + public Project getProject() { + return project; + } + + public Optional<Branch> getBranch() { + return Optional.ofNullable(branch); + } + + public Optional<QualityGate> getQualityGate() { + return Optional.ofNullable(qualityGate); + } + + public Optional<Date> getAnalysisDate() { + return Optional.ofNullable(date).map(Date::new); + } + + public Map<String, String> getProperties() { + return properties; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ProjectAnalysis that = (ProjectAnalysis) o; + return Objects.equals(ceTask, that.ceTask) && + Objects.equals(project, that.project) && + Objects.equals(branch, that.branch) && + Objects.equals(qualityGate, that.qualityGate) && + Objects.equals(date, that.date) && + Objects.equals(properties, that.properties); + } + + @Override + public int hashCode() { + return Objects.hash(ceTask, project, branch, qualityGate, date, properties); + } + + @Override + public String toString() { + return "ProjectAnalysis{" + + "ceTask=" + ceTask + + ", project=" + project + + ", branch=" + branch + + ", qualityGate=" + qualityGate + + ", date=" + date + + ", properties=" + properties + + '}'; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/QualityGate.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/QualityGate.java new file mode 100644 index 00000000000..2133842c6a8 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/QualityGate.java @@ -0,0 +1,211 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.webhook; + +import com.google.common.collect.ImmutableSet; +import java.util.Collection; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import javax.annotation.Nullable; + +import static java.util.Objects.requireNonNull; + +public final class QualityGate { + private final String id; + private final String name; + private final Status status; + private final Set<Condition> conditions; + + public QualityGate(String id, String name, Status status, Set<Condition> conditions) { + this.id = requireNonNull(id, "id can't be null"); + this.name = requireNonNull(name, "name can't be null"); + this.status = requireNonNull(status, "status can't be null"); + this.conditions = ImmutableSet.copyOf(requireNonNull(conditions, "conditions can't be null")); + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public Status getStatus() { + return status; + } + + public Collection<Condition> getConditions() { + return conditions; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + QualityGate that = (QualityGate) o; + return Objects.equals(id, that.id) && + Objects.equals(name, that.name) && + status == that.status && + Objects.equals(conditions, that.conditions); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, status, conditions); + } + + @Override + public String toString() { + return "QualityGate{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", status=" + status + + ", conditions=" + conditions + + '}'; + } + + public enum Status { + OK, + WARN, + ERROR + } + + public static final class Condition { + private final EvaluationStatus status; + private final String metricKey; + private final Operator operator; + private final String errorThreshold; + private final String warnThreshold; + private final boolean onLeakPeriod; + private final String value; + + public Condition(EvaluationStatus status, String metricKey, Operator operator, + @Nullable String errorThreshold, @Nullable String warnThreshold, + boolean onLeakPeriod, @Nullable String value) { + this.status = requireNonNull(status, "status can't be null"); + this.metricKey = requireNonNull(metricKey, "metricKey can't be null"); + this.operator = requireNonNull(operator, "operator can't be null"); + this.errorThreshold = errorThreshold; + this.warnThreshold = warnThreshold; + this.onLeakPeriod = onLeakPeriod; + this.value = value; + } + + public EvaluationStatus getStatus() { + return status; + } + + public String getMetricKey() { + return metricKey; + } + + public Operator getOperator() { + return operator; + } + + public Optional<String> getErrorThreshold() { + return Optional.ofNullable(errorThreshold); + } + + public Optional<String> getWarningThreshold() { + return Optional.ofNullable(warnThreshold); + } + + public boolean isOnLeakPeriod() { + return onLeakPeriod; + } + + public Optional<String> getValue() { + return Optional.ofNullable(value); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Condition condition = (Condition) o; + return onLeakPeriod == condition.onLeakPeriod && + status == condition.status && + Objects.equals(metricKey, condition.metricKey) && + operator == condition.operator && + Objects.equals(errorThreshold, condition.errorThreshold) && + Objects.equals(warnThreshold, condition.warnThreshold) && + Objects.equals(value, condition.value); + } + + @Override + public int hashCode() { + return Objects.hash(status, metricKey, operator, errorThreshold, warnThreshold, onLeakPeriod, value); + } + + @Override + public String toString() { + return "Condition{" + + "status=" + status + + ", metricKey='" + metricKey + '\'' + + ", operator=" + operator + + ", errorThreshold='" + errorThreshold + '\'' + + ", warnThreshold='" + warnThreshold + '\'' + + ", onLeakPeriod=" + onLeakPeriod + + ", value='" + value + '\'' + + '}'; + } + } + + /** + * Quality Gate condition operator. + */ + public enum Operator { + EQUALS, NOT_EQUALS, GREATER_THAN, LESS_THAN + } + + /** + * Quality gate condition evaluation status. + */ + public enum EvaluationStatus { + /** + * No measure found or measure had no value. The condition has not been evaluated and therefor ignored in + * the computation of the Quality Gate status. + */ + NO_VALUE, + /** + * Condition evaluated as OK, neither error nor warning thresholds have been reached. + */ + OK, + /** + * Condition evaluated as WARN, only warning thresholds has been reached. + */ + WARN, + /** + * Condition evaluated as ERROR, error thresholds has been reached (and most likely warning thresholds too). + */ + ERROR + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookModule.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookModule.java index 6a5da0c597b..a33610c3dbb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookModule.java +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookModule.java @@ -27,6 +27,7 @@ public class WebhookModule extends Module { add( WebhookCallerImpl.class, WebhookDeliveryStorage.class, - WebHooksImpl.class); + WebHooksImpl.class, + WebhookPayloadFactoryImpl.class); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactory.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookPayloadFactory.java index 9f5891ae924..bd5b6a8138c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookPayloadFactory.java @@ -17,14 +17,11 @@ * 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.task.projectanalysis.webhook; - -import org.sonar.api.ce.posttask.PostProjectAnalysisTask; -import org.sonar.server.webhook.WebhookPayload; +package org.sonar.server.webhook; @FunctionalInterface public interface WebhookPayloadFactory { - WebhookPayload create(PostProjectAnalysisTask.ProjectAnalysis analysis); + WebhookPayload create(ProjectAnalysis analysis); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookPayloadFactoryImpl.java index 4990f9b3fee..613a0e985f1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookPayloadFactoryImpl.java @@ -17,25 +17,18 @@ * 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.task.projectanalysis.webhook; +package org.sonar.server.webhook; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.net.URLEncoder; import java.util.Date; -import javax.annotation.Nullable; +import java.util.Map; import org.sonar.api.ce.ComputeEngineSide; -import org.sonar.api.ce.posttask.Branch; -import org.sonar.api.ce.posttask.CeTask; -import org.sonar.api.ce.posttask.PostProjectAnalysisTask; -import org.sonar.api.ce.posttask.Project; -import org.sonar.api.ce.posttask.QualityGate; -import org.sonar.api.ce.posttask.ScannerContext; import org.sonar.api.platform.Server; import org.sonar.api.utils.System2; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.server.webhook.WebhookPayload; import static java.lang.String.format; import static org.sonar.core.config.WebhookProperties.ANALYSIS_PROPERTY_PREFIX; @@ -52,7 +45,7 @@ public class WebhookPayloadFactoryImpl implements WebhookPayloadFactory { } @Override - public WebhookPayload create(PostProjectAnalysisTask.ProjectAnalysis analysis) { + public WebhookPayload create(ProjectAnalysis analysis) { Writer string = new StringWriter(); try (JsonWriter writer = JsonWriter.of(string)) { writer.beginObject(); @@ -61,8 +54,8 @@ public class WebhookPayloadFactoryImpl implements WebhookPayloadFactory { writeDates(writer, analysis, system2); writeProject(analysis, writer, analysis.getProject()); analysis.getBranch().ifPresent(b -> writeBranch(writer, analysis.getProject(), b)); - writeQualityGate(writer, analysis.getQualityGate()); - writeAnalysisProperties(writer, analysis.getScannerContext()); + analysis.getQualityGate().ifPresent(qualityGate -> writeQualityGate(writer, qualityGate)); + writeAnalysisProperties(writer, analysis.getProperties()); writer.endObject().close(); return new WebhookPayload(analysis.getProject().getKey(), string.toString()); } @@ -72,12 +65,12 @@ public class WebhookPayloadFactoryImpl implements WebhookPayloadFactory { writer.prop("serverUrl", server.getPublicRootUrl()); } - private static void writeDates(JsonWriter writer, PostProjectAnalysisTask.ProjectAnalysis analysis, System2 system2) { + private static void writeDates(JsonWriter writer, ProjectAnalysis analysis, System2 system2) { analysis.getAnalysisDate().ifPresent(date -> writer.propDateTime("analysedAt", date)); writer.propDateTime("changedAt", analysis.getAnalysisDate().orElseGet(() -> new Date(system2.now()))); } - private void writeProject(PostProjectAnalysisTask.ProjectAnalysis analysis, JsonWriter writer, Project project) { + private void writeProject(ProjectAnalysis analysis, JsonWriter writer, Project project) { writer .name("project") .beginObject() @@ -87,11 +80,11 @@ public class WebhookPayloadFactoryImpl implements WebhookPayloadFactory { .endObject(); } - private static void writeAnalysisProperties(JsonWriter writer, ScannerContext scannerContext) { + private static void writeAnalysisProperties(JsonWriter writer, Map<String, String> properties) { writer .name("properties") .beginObject(); - scannerContext.getProperties().entrySet() + properties.entrySet() .stream() .filter(prop -> prop.getKey().startsWith(ANALYSIS_PROPERTY_PREFIX)) .forEach(prop -> writer.prop(prop.getKey(), prop.getValue())); @@ -132,34 +125,30 @@ public class WebhookPayloadFactoryImpl implements WebhookPayloadFactory { } } - private static void writeQualityGate(JsonWriter writer, @Nullable QualityGate gate) { - if (gate != null) { + private static void writeQualityGate(JsonWriter writer, QualityGate gate) { + writer + .name("qualityGate") + .beginObject() + .prop("name", gate.getName()) + .prop("status", gate.getStatus().toString()) + .name("conditions") + .beginArray(); + for (QualityGate.Condition condition : gate.getConditions()) { writer - .name("qualityGate") .beginObject() - .prop("name", gate.getName()) - .prop("status", gate.getStatus().toString()) - .name("conditions") - .beginArray(); - for (QualityGate.Condition condition : gate.getConditions()) { - writer - .beginObject() - .prop("metric", condition.getMetricKey()) - .prop("operator", condition.getOperator().name()); - if (condition.getStatus() != QualityGate.EvaluationStatus.NO_VALUE) { - writer.prop("value", condition.getValue()); - } - writer - .prop("status", condition.getStatus().name()) - .prop("onLeakPeriod", condition.isOnLeakPeriod()) - .prop("errorThreshold", condition.getErrorThreshold()) - .prop("warningThreshold", condition.getWarningThreshold()) - .endObject(); - } + .prop("metric", condition.getMetricKey()) + .prop("operator", condition.getOperator().name()); + condition.getValue().ifPresent(t -> writer.prop("value", t)); writer - .endArray() + .prop("status", condition.getStatus().name()) + .prop("onLeakPeriod", condition.isOnLeakPeriod()) + .prop("errorThreshold", condition.getErrorThreshold().orElse(null)) + .prop("warningThreshold", condition.getWarningThreshold().orElse(null)) .endObject(); } + writer + .endArray() + .endObject(); } private static String encode(String toEncode) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTaskTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTaskTest.java index 600d7c11335..d398ae6f561 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTaskTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTaskTest.java @@ -19,6 +19,7 @@ */ package org.sonar.server.computation.task.projectanalysis.webhook; +import java.util.Collections; import java.util.Date; import java.util.Random; import java.util.function.Supplier; @@ -26,13 +27,14 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.ce.posttask.CeTask; -import org.sonar.api.ce.posttask.PostProjectAnalysisTask; import org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester; import org.sonar.api.ce.posttask.Project; import org.sonar.api.config.Configuration; import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository; +import org.sonar.server.webhook.ProjectAnalysis; import org.sonar.server.webhook.WebHooks; import org.sonar.server.webhook.WebhookPayload; +import org.sonar.server.webhook.WebhookPayloadFactory; import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; import static org.assertj.core.api.Assertions.assertThat; @@ -57,7 +59,7 @@ public class WebhookPostTaskTest { @Before public void wireMocks() throws Exception { - when(payloadFactory.create(any(PostProjectAnalysisTask.ProjectAnalysis.class))).thenReturn(webhookPayload); + when(payloadFactory.create(any(ProjectAnalysis.class))).thenReturn(webhookPayload); when(configurationRepository.getConfiguration()).thenReturn(configuration); } @@ -72,9 +74,10 @@ public class WebhookPostTaskTest { .setStatus(CeTask.Status.values()[new Random().nextInt(CeTask.Status.values().length)]) .setId(randomAlphanumeric(6)) .build(); + Date date = new Date(); - PostProjectAnalysisTask.ProjectAnalysis projectAnalysis = PostProjectAnalysisTaskTester.of(underTest) - .at(new Date()) + PostProjectAnalysisTaskTester.of(underTest) + .at(date) .withCeTask(ceTask) .withProject(project) .withScannerContext(newScannerContextBuilder().build()) @@ -85,7 +88,14 @@ public class WebhookPostTaskTest { assertThat(supplierCaptor.getValue().get()).isSameAs(webhookPayload); - verify(payloadFactory).create(same(projectAnalysis)); + verify(payloadFactory).create(new ProjectAnalysis( + new org.sonar.server.webhook.CeTask(ceTask.getId(), + org.sonar.server.webhook.CeTask.Status.valueOf(ceTask.getStatus().name())), + new org.sonar.server.webhook.Project(project.getUuid(), project.getKey(), project.getName()), + null, + null, + date.getTime(), + Collections.emptyMap())); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/BranchTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/BranchTest.java new file mode 100644 index 00000000000..af63c4ddfd7 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/BranchTest.java @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.webhook; + +import java.util.Random; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.assertj.core.api.Assertions.assertThat; + +public class BranchTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private Branch underTest = new Branch(true, "b", Branch.Type.SHORT); + + @Test + public void constructor_throws_NPE_if_type_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("type can't be null"); + + new Branch(new Random().nextBoolean(), "s", null); + } + + @Test + public void verify_getters() { + assertThat(underTest.isMain()).isTrue(); + assertThat(underTest.getName()).contains("b"); + assertThat(underTest.getType()).isEqualTo(Branch.Type.SHORT); + + + Branch underTestWithNull = new Branch(false, null, Branch.Type.LONG); + assertThat(underTestWithNull.isMain()).isFalse(); + assertThat(underTestWithNull.getName()).isEmpty(); + assertThat(underTestWithNull.getType()).isEqualTo(Branch.Type.LONG); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/CeTaskTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/CeTaskTest.java new file mode 100644 index 00000000000..502bde02926 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/CeTaskTest.java @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.webhook; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CeTaskTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private CeTask underTest = new CeTask("A", CeTask.Status.SUCCESS); + + @Test + public void constructor_throws_NPE_if_id_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("id can't be null"); + + new CeTask(null, CeTask.Status.SUCCESS); + } + + @Test + public void constructor_throws_NPE_if_status_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("status can't be null"); + + new CeTask("B", null); + } + + @Test + public void verify_getters() { + assertThat(underTest.getId()).isEqualTo("A"); + assertThat(underTest.getStatus()).isEqualTo(CeTask.Status.SUCCESS); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/ProjectAnalysisTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/ProjectAnalysisTest.java new file mode 100644 index 00000000000..1cad78c7c02 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/ProjectAnalysisTest.java @@ -0,0 +1,150 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.webhook; + +import com.google.common.collect.ImmutableMap; +import java.util.Date; +import java.util.Map; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static java.util.Collections.emptyMap; +import static java.util.Collections.emptySet; +import static org.assertj.core.api.Assertions.assertThat; + +public class ProjectAnalysisTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private final CeTask ceTask = new CeTask("id", CeTask.Status.SUCCESS); + private final Project project = new Project("uuid", "key", "name"); + private final Branch branch = new Branch(true, "name", Branch.Type.SHORT); + private final QualityGate qualityGate = new QualityGate("id", "name", QualityGate.Status.WARN, emptySet()); + private final Map<String, String> properties = ImmutableMap.of("a", "b"); + private ProjectAnalysis underTest = new ProjectAnalysis(ceTask, + project, + branch, + qualityGate, + 1L, + properties); + + @Test + public void constructor_throws_NPE_if_ceTask_is_null() { + + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("ceTask can't be null"); + + new ProjectAnalysis(null, + project, + branch, + qualityGate, + 1L, + emptyMap()); + } + + @Test + public void constructor_throws_NPE_if_project_is_null() { + + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("project can't be null"); + + new ProjectAnalysis(ceTask, + null, + branch, + qualityGate, + 1L, + emptyMap()); + } + + @Test + public void constructor_throws_NPE_if_properties_is_null() { + + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("properties can't be null"); + + new ProjectAnalysis(ceTask, + project, + branch, + qualityGate, + 1L, + null); + } + + @Test + public void verify_getters() { + assertThat(underTest.getCeTask()).isSameAs(ceTask); + assertThat(underTest.getProject()).isSameAs(project); + assertThat(underTest.getBranch().get()).isSameAs(branch); + assertThat(underTest.getQualityGate().get()).isSameAs(qualityGate); + assertThat(underTest.getAnalysisDate()).contains(new Date(1L)); + assertThat(underTest.getProperties()).isEqualTo(properties); + + ProjectAnalysis underTestWithNulls = new ProjectAnalysis(ceTask, project, null, null, null, emptyMap()); + assertThat(underTestWithNulls.getBranch()).isEmpty(); + assertThat(underTestWithNulls.getQualityGate()).isEmpty(); + assertThat(underTestWithNulls.getAnalysisDate()).isEmpty(); + assertThat(underTestWithNulls.getProperties()).isEmpty(); + } + + @Test + public void defines_equals_based_on_all_fields() { + assertThat(underTest).isEqualTo(underTest); + assertThat(underTest).isEqualTo(new ProjectAnalysis(ceTask, project, branch, qualityGate, 1L, properties)); + assertThat(underTest).isNotEqualTo(null); + assertThat(underTest).isNotEqualTo(new Object()); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(new CeTask("2", CeTask.Status.SUCCESS), project, branch, qualityGate, 1L, properties)); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(ceTask, new Project("A", "B", "C"), branch, qualityGate, 1L, properties)); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(ceTask, new Project("A", "B", "C"), branch, qualityGate, 1L, properties)); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(ceTask, project, null, qualityGate, 1L, properties)); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(ceTask, project, new Branch(false, "B", Branch.Type.SHORT), qualityGate, 1L, properties)); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, null, 1L, properties)); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, new QualityGate("A", "B", QualityGate.Status.WARN, emptySet()), 1L, properties)); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, qualityGate, null, properties)); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, qualityGate, 2L, properties)); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, qualityGate, 1L, emptyMap())); + assertThat(underTest).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, qualityGate, 1L, ImmutableMap.of("A", "B"))); + } + + @Test + public void defines_hashcode_based_on_all_fields() { + assertThat(underTest.hashCode()).isEqualTo(underTest.hashCode()); + assertThat(underTest.hashCode()).isEqualTo(new ProjectAnalysis(ceTask, project, branch, qualityGate, 1L, properties).hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new Object().hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(new CeTask("2", CeTask.Status.SUCCESS), project, branch, qualityGate, 1L, properties).hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(ceTask, new Project("A", "B", "C"), branch, qualityGate, 1L, properties).hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(ceTask, new Project("A", "B", "C"), branch, qualityGate, 1L, properties).hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(ceTask, project, null, qualityGate, 1L, properties).hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(ceTask, project, new Branch(false, "B", Branch.Type.SHORT), qualityGate, 1L, properties).hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, null, 1L, properties).hashCode()); + assertThat(underTest.hashCode()) + .isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, new QualityGate("A", "B", QualityGate.Status.WARN, emptySet()), 1L, properties).hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, qualityGate, null, properties).hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, qualityGate, 2L, properties).hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, qualityGate, 1L, emptyMap()).hashCode()); + assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(ceTask, project, branch, qualityGate, 1L, ImmutableMap.of("B", "C")).hashCode()); + } + + @Test + public void verify_toString() { + assertThat(underTest.toString()).isEqualTo( + "ProjectAnalysis{ceTask=CeTask{id='id', status=SUCCESS}, project=Project{uuid='uuid', key='key', name='name'}, branch=Branch{main=true, name='name', type=SHORT}, qualityGate=QualityGate{id='id', name='name', status=WARN, conditions=[]}, date=1, properties={a=b}}"); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/ProjectTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/ProjectTest.java new file mode 100644 index 00000000000..adf6036c1fd --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/ProjectTest.java @@ -0,0 +1,64 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.webhook; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ProjectTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private Project underTest = new Project("a", "b", "c"); + + @Test + public void constructor_throws_NPE_if_uuid_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("uuid can't be null"); + + new Project(null, "b", "c"); + } + + @Test + public void constructor_throws_NPE_if_key_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("key can't be null"); + + new Project("a", null, "c"); + } + + @Test + public void constructor_throws_NPE_if_name_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("name can't be null"); + + new Project("a", "b", null); + } + + @Test + public void verify_getters() { + assertThat(underTest.getUuid()).isEqualTo("a"); + assertThat(underTest.getKey()).isEqualTo("b"); + assertThat(underTest.getName()).isEqualTo("c"); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/QualityGateTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/QualityGateTest.java new file mode 100644 index 00000000000..b75c4673764 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/QualityGateTest.java @@ -0,0 +1,122 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.webhook; + +import java.util.Random; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static java.util.Collections.singleton; +import static org.assertj.core.api.Assertions.assertThat; + +public class QualityGateTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private final Random random = new Random(); + private boolean onLeak = random.nextBoolean(); + private QualityGate.EvaluationStatus randomEvaluationStatus = QualityGate.EvaluationStatus.values()[random.nextInt(QualityGate.EvaluationStatus.values().length)]; + private QualityGate.Condition condition = new QualityGate.Condition( + randomEvaluationStatus, "k", QualityGate.Operator.GREATER_THAN, "l", "m", onLeak, "val"); + private QualityGate.Status randomStatus = QualityGate.Status.values()[random.nextInt(QualityGate.Status.values().length)]; + private QualityGate underTest = new QualityGate("i", "j", randomStatus, singleton(condition)); + + @Test + public void constructor_throws_NPE_if_id_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("id can't be null"); + + new QualityGate(null, "j", QualityGate.Status.WARN, singleton(condition)); + } + + @Test + public void constructor_throws_NPE_if_name_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("name can't be null"); + + new QualityGate("i", null, QualityGate.Status.WARN, singleton(condition)); + } + + @Test + public void constructor_throws_NPE_if_status_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("status can't be null"); + + new QualityGate("i", "j", null, singleton(condition)); + } + + @Test + public void constructor_throws_NPE_if_conditions_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("conditions can't be null"); + + new QualityGate("i", "j", QualityGate.Status.WARN, null); + } + + @Test + public void condition_constructor_throws_NPE_if_evaluation_status_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("status can't be null"); + + new QualityGate.Condition(null, "k", QualityGate.Operator.GREATER_THAN, "l", "m", onLeak, "val"); + } + + @Test + public void condition_constructor_throws_NPE_if_metricKey_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("metricKey can't be null"); + + new QualityGate.Condition(randomEvaluationStatus, null, QualityGate.Operator.GREATER_THAN, "l", "m", onLeak, "val"); + } + + @Test + public void condition_constructor_throws_NPE_if_operator_status_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("operator can't be null"); + + new QualityGate.Condition(randomEvaluationStatus, "k", null, "l", "m", onLeak, "val"); + } + + @Test + public void verify_getters() { + assertThat(underTest.getId()).isEqualTo("i"); + assertThat(underTest.getName()).isEqualTo("j"); + assertThat(underTest.getStatus()).isEqualTo(randomStatus); + assertThat(underTest.getConditions()).isEqualTo(singleton(condition)); + } + + @Test + public void verify_condition_getters() { + assertThat(condition.getStatus()).isEqualTo(randomEvaluationStatus); + assertThat(condition.getMetricKey()).isEqualTo("k"); + assertThat(condition.getErrorThreshold()).contains("l"); + assertThat(condition.getWarningThreshold()).contains("m"); + assertThat(condition.isOnLeakPeriod()).isEqualTo(onLeak); + assertThat(condition.getValue()).contains("val"); + + QualityGate.Condition conditionWithNulls = new QualityGate.Condition( + randomEvaluationStatus, "k", QualityGate.Operator.GREATER_THAN, null, null, onLeak, null); + + assertThat(conditionWithNulls.getErrorThreshold()).isEmpty(); + assertThat(conditionWithNulls.getWarningThreshold()).isEmpty(); + assertThat(conditionWithNulls.getValue()).isEmpty(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/TestWebhookPayloadFactory.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/TestWebhookPayloadFactory.java deleted file mode 100644 index 603b8ee3861..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/webhook/TestWebhookPayloadFactory.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 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.webhook; - -import org.sonar.api.ce.posttask.PostProjectAnalysisTask; -import org.sonar.server.computation.task.projectanalysis.webhook.WebhookPayloadFactory; - -public class TestWebhookPayloadFactory implements WebhookPayloadFactory { - - private static final String FAKE_JSON = "{\"payload\": true}"; - - @Override - public WebhookPayload create(PostProjectAnalysisTask.ProjectAnalysis analysis) { - return new WebhookPayload(analysis.getProject().getKey(), FAKE_JSON); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookModuleTest.java index 5a80a0b7459..6c29df54a4d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookModuleTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookModuleTest.java @@ -40,6 +40,6 @@ public class WebhookModuleTest { underTest.configure(container); - assertThat(container.size()).isEqualTo(3 + COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER); + assertThat(container.size()).isEqualTo(4 + COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookPayloadFactoryImplTest.java index e4c409f2019..56aea60cf48 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookPayloadFactoryImplTest.java @@ -17,35 +17,22 @@ * 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.task.projectanalysis.webhook; +package org.sonar.server.webhook; import com.google.common.collect.ImmutableMap; -import java.util.Date; import java.util.Map; -import java.util.Optional; import javax.annotation.Nullable; import org.junit.Before; import org.junit.Test; -import org.sonar.api.ce.posttask.Branch; -import org.sonar.api.ce.posttask.CeTask; -import org.sonar.api.ce.posttask.PostProjectAnalysisTask; -import org.sonar.api.ce.posttask.Project; -import org.sonar.api.ce.posttask.QualityGate; -import org.sonar.api.ce.posttask.ScannerContext; import org.sonar.api.platform.Server; import org.sonar.api.utils.System2; -import org.sonar.server.computation.task.projectanalysis.api.posttask.BranchImpl; -import org.sonar.server.webhook.WebhookPayload; import static java.util.Collections.emptyMap; +import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newCeTaskBuilder; -import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newConditionBuilder; -import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newProjectBuilder; -import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newQualityGateBuilder; -import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newScannerContextBuilder; import static org.sonar.test.JsonAssert.assertJson; public class WebhookPayloadFactoryImplTest { @@ -64,23 +51,11 @@ public class WebhookPayloadFactoryImplTest { @Test public void create_payload_for_successful_analysis() { - CeTask task = newCeTaskBuilder() - .setStatus(CeTask.Status.SUCCESS) - .setId("#1") - .build(); - QualityGate gate = newQualityGateBuilder() - .setId("G1") - .setName("Gate One") - .setStatus(QualityGate.Status.WARN) - .add(newConditionBuilder() - .setMetricKey("coverage") - .setOperator(QualityGate.Operator.GREATER_THAN) - .setOnLeakPeriod(true) - .setWarningThreshold("75.0") - .setErrorThreshold("70.0") - .build(QualityGate.EvaluationStatus.WARN, "74.0")) - .build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, emptyMap()); + CeTask task = new CeTask("#1", CeTask.Status.SUCCESS); + QualityGate gate = new QualityGate("G1", "Gate One", QualityGate.Status.WARN, singleton(new QualityGate.Condition( + QualityGate.EvaluationStatus.WARN, + "coverage", QualityGate.Operator.GREATER_THAN, "70.0", "75.0", true, "74.0"))); + ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, emptyMap()); WebhookPayload payload = underTest.create(analysis); assertThat(payload.getProjectKey()).isEqualTo(PROJECT_KEY); @@ -118,22 +93,10 @@ public class WebhookPayloadFactoryImplTest { @Test public void create_payload_with_gate_conditions_without_value() { - CeTask task = newCeTaskBuilder() - .setStatus(CeTask.Status.SUCCESS) - .setId("#1") - .build(); - QualityGate gate = newQualityGateBuilder() - .setId("G1") - .setName("Gate One") - .setStatus(QualityGate.Status.WARN) - .add(newConditionBuilder() - .setMetricKey("coverage") - .setOperator(QualityGate.Operator.GREATER_THAN) - .setWarningThreshold("75.0") - .setErrorThreshold("70.0") - .buildNoValue()) - .build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, emptyMap()); + CeTask task = new CeTask("#1", CeTask.Status.SUCCESS); + QualityGate gate = new QualityGate("G1", "Gate One", QualityGate.Status.WARN, singleton( + new QualityGate.Condition(QualityGate.EvaluationStatus.NO_VALUE, "coverage", QualityGate.Operator.GREATER_THAN, "70.0", "75.0", false, null))); + ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, emptyMap()); WebhookPayload payload = underTest.create(analysis); assertThat(payload.getProjectKey()).isEqualTo(PROJECT_KEY); @@ -168,21 +131,14 @@ public class WebhookPayloadFactoryImplTest { @Test public void create_payload_with_analysis_properties() { - CeTask task = newCeTaskBuilder() - .setStatus(CeTask.Status.SUCCESS) - .setId("#1") - .build(); - QualityGate gate = newQualityGateBuilder() - .setId("G1") - .setName("Gate One") - .setStatus(QualityGate.Status.WARN) - .build(); + CeTask task = new CeTask("#1", CeTask.Status.SUCCESS); + QualityGate gate = new QualityGate("G1", "Gate One", QualityGate.Status.WARN, emptySet()); Map<String, String> scannerProperties = ImmutableMap.of( "sonar.analysis.revision", "ab45d24", "sonar.analysis.buildNumber", "B123", "not.prefixed.with.sonar.analysis", "should be ignored", "ignored", "should be ignored too"); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, scannerProperties); + ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, scannerProperties); WebhookPayload payload = underTest.create(analysis); assertJson(payload.getJson()) @@ -215,8 +171,8 @@ public class WebhookPayloadFactoryImplTest { @Test public void create_payload_for_failed_analysis() { - CeTask ceTask = newCeTaskBuilder().setStatus(CeTask.Status.FAILED).setId("#1").build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(ceTask, null, null, 1_500_000_000_000L, emptyMap()); + CeTask ceTask = new CeTask("#1", CeTask.Status.FAILED); + ProjectAnalysis analysis = newAnalysis(ceTask, null, null, 1_500_000_000_000L, emptyMap()); WebhookPayload payload = underTest.create(analysis); @@ -239,8 +195,8 @@ public class WebhookPayloadFactoryImplTest { @Test public void create_payload_for_no_analysis_date() { - CeTask ceTask = newCeTaskBuilder().setStatus(CeTask.Status.FAILED).setId("#1").build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(ceTask, null, null, null, emptyMap()); + CeTask ceTask = new CeTask("#1", CeTask.Status.FAILED); + ProjectAnalysis analysis = newAnalysis(ceTask, null, null, null, emptyMap()); WebhookPayload payload = underTest.create(analysis); @@ -262,11 +218,8 @@ public class WebhookPayloadFactoryImplTest { @Test public void create_payload_on_short_branch() { - CeTask task = newCeTaskBuilder() - .setStatus(CeTask.Status.SUCCESS) - .setId("#1") - .build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, null, new BranchImpl(false, "feature/foo", Branch.Type.SHORT), 1_500_000_000_000L, emptyMap()); + CeTask task = new CeTask("#1", CeTask.Status.SUCCESS); + ProjectAnalysis analysis = newAnalysis(task, null, new Branch(false, "feature/foo", Branch.Type.SHORT), 1_500_000_000_000L, emptyMap()); WebhookPayload payload = underTest.create(analysis); assertJson(payload.getJson()) @@ -282,11 +235,8 @@ public class WebhookPayloadFactoryImplTest { @Test public void create_payload_on_long_branch() { - CeTask task = newCeTaskBuilder() - .setStatus(CeTask.Status.SUCCESS) - .setId("#1") - .build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, null, new BranchImpl(false, "feature/foo", Branch.Type.LONG), 1_500_000_000_000L, emptyMap()); + CeTask task = new CeTask("#1", CeTask.Status.SUCCESS); + ProjectAnalysis analysis = newAnalysis(task, null, new Branch(false, "feature/foo", Branch.Type.LONG), 1_500_000_000_000L, emptyMap()); WebhookPayload payload = underTest.create(analysis); assertJson(payload.getJson()) @@ -302,11 +252,8 @@ public class WebhookPayloadFactoryImplTest { @Test public void create_payload_on_main_branch_without_name() { - CeTask task = newCeTaskBuilder() - .setStatus(CeTask.Status.SUCCESS) - .setId("#1") - .build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, null, new BranchImpl(true, null, Branch.Type.LONG), 1_500_000_000_000L, emptyMap()); + CeTask task = new CeTask("#1", CeTask.Status.SUCCESS); + ProjectAnalysis analysis = newAnalysis(task, null, new Branch(true, null, Branch.Type.LONG), 1_500_000_000_000L, emptyMap()); WebhookPayload payload = underTest.create(analysis); assertJson(payload.getJson()) @@ -319,50 +266,9 @@ public class WebhookPayloadFactoryImplTest { "}"); } - private static PostProjectAnalysisTask.ProjectAnalysis newAnalysis(CeTask task, @Nullable QualityGate gate, + private static ProjectAnalysis newAnalysis(CeTask task, @Nullable QualityGate gate, @Nullable Branch branch, @Nullable Long analysisDate, Map<String, String> scannerProperties) { - return new PostProjectAnalysisTask.ProjectAnalysis() { - @Override - public CeTask getCeTask() { - return task; - } - - @Override - public Project getProject() { - return newProjectBuilder() - .setUuid("P1_UUID") - .setKey(PROJECT_KEY) - .setName("Project One") - .build(); - } - - @Override - public Optional<Branch> getBranch() { - return Optional.ofNullable(branch); - } - - @Override - public QualityGate getQualityGate() { - return gate; - } - - @Override - public Date getDate() { - throw new UnsupportedOperationException(); - } - - @Override - public Optional<Date> getAnalysisDate() { - return Optional.ofNullable(analysisDate).map(Date::new); - } - - @Override - public ScannerContext getScannerContext() { - return newScannerContextBuilder() - .addProperties(scannerProperties) - .build(); - } - }; + return new ProjectAnalysis(task, new Project("P1_UUID", PROJECT_KEY, "Project One"), branch, gate, analysisDate, scannerProperties); } } |