Browse Source

SONAR-9871 move WebhookPayloadFactory to share it with web

tags/6.7-RC1
Sébastien Lesaint 6 years ago
parent
commit
1613b1f008
19 changed files with 1097 additions and 208 deletions
  1. 0
    2
      server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java
  2. 29
    1
      server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTask.java
  3. 82
    0
      server/sonar-server/src/main/java/org/sonar/server/webhook/Branch.java
  4. 72
    0
      server/sonar-server/src/main/java/org/sonar/server/webhook/CeTask.java
  5. 76
    0
      server/sonar-server/src/main/java/org/sonar/server/webhook/Project.java
  6. 106
    0
      server/sonar-server/src/main/java/org/sonar/server/webhook/ProjectAnalysis.java
  7. 211
    0
      server/sonar-server/src/main/java/org/sonar/server/webhook/QualityGate.java
  8. 2
    1
      server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookModule.java
  9. 2
    5
      server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookPayloadFactory.java
  10. 28
    39
      server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookPayloadFactoryImpl.java
  11. 15
    5
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTaskTest.java
  12. 55
    0
      server/sonar-server/src/test/java/org/sonar/server/webhook/BranchTest.java
  13. 55
    0
      server/sonar-server/src/test/java/org/sonar/server/webhook/CeTaskTest.java
  14. 150
    0
      server/sonar-server/src/test/java/org/sonar/server/webhook/ProjectAnalysisTest.java
  15. 64
    0
      server/sonar-server/src/test/java/org/sonar/server/webhook/ProjectTest.java
  16. 122
    0
      server/sonar-server/src/test/java/org/sonar/server/webhook/QualityGateTest.java
  17. 0
    33
      server/sonar-server/src/test/java/org/sonar/server/webhook/TestWebhookPayloadFactory.java
  18. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookModuleTest.java
  19. 27
    121
      server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookPayloadFactoryImplTest.java

+ 0
- 2
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java View File

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


+ 29
- 1
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTask.java View File

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

}

+ 82
- 0
server/sonar-server/src/main/java/org/sonar/server/webhook/Branch.java View File

@@ -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 +
'}';
}
}

+ 72
- 0
server/sonar-server/src/main/java/org/sonar/server/webhook/CeTask.java View File

@@ -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 +
'}';
}
}

+ 76
- 0
server/sonar-server/src/main/java/org/sonar/server/webhook/Project.java View File

@@ -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 + '\'' +
'}';
}
}

+ 106
- 0
server/sonar-server/src/main/java/org/sonar/server/webhook/ProjectAnalysis.java View File

@@ -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 +
'}';
}
}

+ 211
- 0
server/sonar-server/src/main/java/org/sonar/server/webhook/QualityGate.java View File

@@ -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
}
}

+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookModule.java View File

@@ -27,6 +27,7 @@ public class WebhookModule extends Module {
add(
WebhookCallerImpl.class,
WebhookDeliveryStorage.class,
WebHooksImpl.class);
WebHooksImpl.class,
WebhookPayloadFactoryImpl.class);
}
}

server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactory.java → server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookPayloadFactory.java View File

@@ -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);

}

server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImpl.java → server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookPayloadFactoryImpl.java View File

@@ -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) {

+ 15
- 5
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTaskTest.java View File

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

}

+ 55
- 0
server/sonar-server/src/test/java/org/sonar/server/webhook/BranchTest.java View File

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

+ 55
- 0
server/sonar-server/src/test/java/org/sonar/server/webhook/CeTaskTest.java View File

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

+ 150
- 0
server/sonar-server/src/test/java/org/sonar/server/webhook/ProjectAnalysisTest.java View File

@@ -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}}");
}
}

+ 64
- 0
server/sonar-server/src/test/java/org/sonar/server/webhook/ProjectTest.java View File

@@ -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");
}
}

+ 122
- 0
server/sonar-server/src/test/java/org/sonar/server/webhook/QualityGateTest.java View File

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

+ 0
- 33
server/sonar-server/src/test/java/org/sonar/server/webhook/TestWebhookPayloadFactory.java View File

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

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookModuleTest.java View File

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

server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImplTest.java → server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookPayloadFactoryImplTest.java View File

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

}

Loading…
Cancel
Save