1
0
mirror of https://github.com/jenkinsci/mattermost-plugin.git synced 2024-11-24 08:12:36 +02:00

Apply spotless code formatting

Signed-off-by: Jo Vandeginste <Jo.Vandeginste@kuleuven.be>
This commit is contained in:
Jo Vandeginste 2019-10-19 20:40:01 +02:00
parent 97c65fc685
commit bbc95656b6
No known key found for this signature in database
GPG Key ID: E349B1AD928B72FB
17 changed files with 1393 additions and 1280 deletions

341
pom.xml
View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<modelVersion>4.0.0</modelVersion>
<!-- change to this parent to compare building this plugin for Hudson -->
<!--
<!-- change to this parent to compare building this plugin for Hudson -->
<!--
<parent>
<groupId>org.jvnet.hudson.plugins</groupId>
<artifactId>hudson-plugin-parent</artifactId>
@ -12,9 +12,9 @@
-->
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>2.11</version>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>2.11</version>
</parent>
<artifactId>mattermost</artifactId>
@ -25,135 +25,135 @@
<url>https://wiki.jenkins-ci.org/display/JENKINS/Mattermost+Plugin</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<workflow.version>1.11</workflow.version>
<hamcrest.version>1.3</hamcrest.version>
<jenkins.version>2.0</jenkins.version>
<java.level>8</java.level>
<jenkins-test-harness.version>2.13</jenkins-test-harness.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<workflow.version>1.11</workflow.version>
<hamcrest.version>1.3</hamcrest.version>
<jenkins.version>2.0</jenkins.version>
<java.level>8</java.level>
<jenkins-test-harness.version>2.13</jenkins-test-harness.version>
</properties>
<licenses>
<license>
<name>MIT license</name>
<comments>All source code is under the MIT license.</comments>
<url>http://opensource.org/licenses/MIT</url>
</license>
<license>
<name>MIT license</name>
<comments>All source code is under the MIT license.</comments>
<url>http://opensource.org/licenses/MIT</url>
</license>
</licenses>
<scm>
<connection>scm:git:ssh://git@github.com/jenkinsci/mattermost-plugin.git</connection>
<developerConnection>scm:git:ssh://git@github.com/jenkinsci/mattermost-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/mattermost-plugin</url>
<tag>mattermost-2.0</tag>
<connection>scm:git:ssh://git@github.com/jenkinsci/mattermost-plugin.git</connection>
<developerConnection>scm:git:ssh://git@github.com/jenkinsci/mattermost-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/mattermost-plugin</url>
<tag>mattermost-2.0</tag>
</scm>
<dependencies>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>junit</artifactId>
<version>1.18</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9.1</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20131018</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
<scope>test</scope>
</dependency>
<!-- only here to prevent from being included inside hpi for hudson parent, not needed by project at all -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.9</version>
<scope>provided</scope>
</dependency>
<!-- only here to prevent from being included inside hpi for hudson parent, not needed by project at all -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
<scope>provided</scope>
</dependency>
<!--
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>junit</artifactId>
<version>1.18</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9.1</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20131018</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
<scope>test</scope>
</dependency>
<!-- only here to prevent from being included inside hpi for hudson parent, not needed by project at all -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.9</version>
<scope>provided</scope>
</dependency>
<!-- only here to prevent from being included inside hpi for hudson parent, not needed by project at all -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
<scope>provided</scope>
</dependency>
<!--
Adding JNA to fix failing unit tests on Ubuntu 14.04
https://bugs.launchpad.net/ubuntu/+source/libjna-java/+bug/1065253
-->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>3.2.2</version>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>3.2.2</version>
</dependency>
<!-- for workflow support -->
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>${workflow.version}</version>
<optional>true</optional>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>${workflow.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<version>${workflow.version}</version>
<scope>test</scope>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<version>${workflow.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>${workflow.version}</version>
<scope>test</scope>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>${workflow.version}</version>
<scope>test</scope>
</dependency>
<dependency> <!-- StepConfigTester -->
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<classifier>tests</classifier>
<version>${workflow.version}</version>
<scope>test</scope>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<classifier>tests</classifier>
<version>${workflow.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
@ -171,75 +171,90 @@
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
<plugins>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<tagNameFormat>mattermost-@{project.version}</tagNameFormat>
</configuration>
</plugin>
<plugin>
<groupId>org.jenkins-ci.tools</groupId>
<artifactId>maven-hpi-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<compatibleSinceVersion>2.4.0</compatibleSinceVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<trimStackTrace>false</trimStackTrace>
</configuration>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<tagNameFormat>mattermost-@{project.version}</tagNameFormat>
</configuration>
</plugin>
<plugin>
<groupId>org.jenkins-ci.tools</groupId>
<artifactId>maven-hpi-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<compatibleSinceVersion>2.4.0</compatibleSinceVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<trimStackTrace>false</trimStackTrace>
</configuration>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>1.25.1</version>
<configuration>
<java>
<googleJavaFormat>
<!-- Optional, available versions: https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.google.googlejavaformat%22%20AND%20a%3A%22google-java-format%22 -->
<version>1.5</version>
<!-- Optional, available versions: GOOGLE, AOSP https://github.com/google/google-java-format/blob/master/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java -->
<style>GOOGLE</style>
</googleJavaFormat>
</java>
</configuration>
</plugin>
</plugins>
</build>
</build>
<repositories>
<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>
</repositories>
<pluginRepositories>
<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
</pluginRepositories>
<!--
<!--
The developers show up as current maintainers in the Jenkins wiki.
https://wiki.jenkins-ci.org/display/JENKINS/Mattermost+Plugin
The id should be the jenkinsci.org username and not your GitHub username.
-->
<developers>
<developer>
<id>jovandeginste</id>
<name>Jo Vandeginste</name>
<email>jo.vandeginste@gmail.com</email>
<url>https://github.com/jovandeginste</url>
<roles>
<role>maintainer</role>
</roles>
<timezone>Europe/Brussels</timezone>
</developer>
<developer>
<id>eirikwang</id>
<name>Eirik Wang</name>
<email>eirilwan@gmail.com</email>
<url>https://github.com/eirikwang</url>
<roles>
<role>committer</role>
</roles>
<timezone>Europe/Brussels</timezone>
</developer>
<developer>
<id>jovandeginste</id>
<name>Jo Vandeginste</name>
<email>jo.vandeginste@gmail.com</email>
<url>https://github.com/jovandeginste</url>
<roles>
<role>maintainer</role>
</roles>
<timezone>Europe/Brussels</timezone>
</developer>
<developer>
<id>eirikwang</id>
<name>Eirik Wang</name>
<email>eirilwan@gmail.com</email>
<url>https://github.com/eirikwang</url>
<roles>
<role>committer</role>
</roles>
<timezone>Europe/Brussels</timezone>
</developer>
</developers>
</project>
</project>

View File

@ -1,11 +1,7 @@
package jenkins.plugins.mattermost;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.SEVERE;
import hudson.EnvVars;
import hudson.Util;
@ -23,416 +19,432 @@ import hudson.scm.ChangeLogSet.Entry;
import hudson.tasks.test.AbstractTestResultAction;
import hudson.triggers.SCMTrigger;
import hudson.util.LogTaskListener;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import org.apache.commons.lang.StringUtils;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.SEVERE;
@SuppressWarnings("rawtypes")
public class ActiveNotifier implements FineGrainedNotifier {
private static final Logger logger = Logger.getLogger(MattermostListener.class.getName());
private static final Logger logger = Logger.getLogger(MattermostListener.class.getName());
MattermostNotifier notifier;
BuildListener listener;
MattermostNotifier notifier;
BuildListener listener;
public ActiveNotifier(MattermostNotifier notifier, BuildListener listener) {
super();
this.notifier = notifier;
this.listener = listener;
}
public ActiveNotifier(MattermostNotifier notifier, BuildListener listener) {
super();
this.notifier = notifier;
this.listener = listener;
}
private MattermostService getMattermost(AbstractBuild r) {
return notifier.newMattermostService(r, listener);
}
private MattermostService getMattermost(AbstractBuild r) {
return notifier.newMattermostService(r, listener);
}
public void deleted(AbstractBuild r) {
}
public void deleted(AbstractBuild r) {}
public void started(AbstractBuild build) {
public void started(AbstractBuild build) {
//AbstractProject<?, ?> project = build.getProject();
// AbstractProject<?, ?> project = build.getProject();
CauseAction causeAction = build.getAction(CauseAction.class);
CauseAction causeAction = build.getAction(CauseAction.class);
if (causeAction != null) {
Cause scmCause = causeAction.findCause(SCMTrigger.SCMTriggerCause.class);
if (scmCause == null) {
MessageBuilder message = new MessageBuilder(notifier, build);
message.append(causeAction.getShortDescription());
notifyStart(build, message.appendOpenLink().toString());
// Cause was found, exit early to prevent double-message
return;
}
}
if (causeAction != null) {
Cause scmCause = causeAction.findCause(SCMTrigger.SCMTriggerCause.class);
if (scmCause == null) {
MessageBuilder message = new MessageBuilder(notifier, build);
message.append(causeAction.getShortDescription());
notifyStart(build, message.appendOpenLink().toString());
// Cause was found, exit early to prevent double-message
return;
}
}
String changes = getChanges(build, notifier.getIncludeCustomAttachmentMessage());
if (changes != null) {
notifyStart(build, changes);
} else {
notifyStart(build, getBuildStatusMessage(build, false, notifier.getIncludeCustomAttachmentMessage()));
}
}
String changes = getChanges(build, notifier.getIncludeCustomAttachmentMessage());
if (changes != null) {
notifyStart(build, changes);
} else {
notifyStart(
build, getBuildStatusMessage(build, false, notifier.getIncludeCustomAttachmentMessage()));
}
}
private void notifyStart(AbstractBuild build, String attachmentMessage) {
AbstractProject<?, ?> project = (build != null) ? build.getProject() : null;
AbstractBuild<?, ?> previousBuild = (project != null && project.getLastBuild() != null) ? project.getLastBuild().getPreviousCompletedBuild() : null;
String expandedCustomMessage = getExpandedCustomMessage(build);
if (previousBuild == null) {
getMattermost(build).publish(attachmentMessage, expandedCustomMessage, "good");
} else {
getMattermost(build).publish(attachmentMessage, expandedCustomMessage, getBuildColor(previousBuild));
}
}
private void notifyStart(AbstractBuild build, String attachmentMessage) {
AbstractProject<?, ?> project = (build != null) ? build.getProject() : null;
AbstractBuild<?, ?> previousBuild =
(project != null && project.getLastBuild() != null)
? project.getLastBuild().getPreviousCompletedBuild()
: null;
String expandedCustomMessage = getExpandedCustomMessage(build);
if (previousBuild == null) {
getMattermost(build).publish(attachmentMessage, expandedCustomMessage, "good");
} else {
getMattermost(build)
.publish(attachmentMessage, expandedCustomMessage, getBuildColor(previousBuild));
}
}
public void finalized(AbstractBuild r) {
}
public void finalized(AbstractBuild r) {}
public void completed(AbstractBuild r) {
AbstractProject<?, ?> project = r.getProject();
Result result = r.getResult();
AbstractBuild<?, ?> previousBuild = project.getLastBuild();
if (previousBuild != null) {
do {
previousBuild = previousBuild.getPreviousCompletedBuild();
} while (previousBuild != null && previousBuild.getResult() == Result.ABORTED);
}
Result previousResult = (previousBuild != null) ? previousBuild.getResult() : Result.SUCCESS;
if ((result == Result.ABORTED && notifier.getNotifyAborted())
|| (result == Result.FAILURE //notify only on single failed build
&& previousResult != Result.FAILURE
&& notifier.getNotifyFailure())
|| (result == Result.FAILURE //notify only on repeated failures
&& previousResult == Result.FAILURE
&& notifier.getNotifyRepeatedFailure())
|| (result == Result.NOT_BUILT && notifier.getNotifyNotBuilt())
|| (result == Result.SUCCESS
&& (previousResult == Result.FAILURE || previousResult == Result.UNSTABLE)
&& notifier.getNotifyBackToNormal())
|| (result == Result.SUCCESS && notifier.getNotifySuccess())
|| (result == Result.UNSTABLE && notifier.getNotifyUnstable())) {
String expandedCustomMessage = getExpandedCustomMessage(r);
getMattermost(r).publish(getBuildStatusMessage(r, notifier.getIncludeTestSummary(),
notifier.getIncludeCustomAttachmentMessage()), expandedCustomMessage, getBuildColor(r));
if (notifier.getCommitInfoChoice().showAnything()) {
getMattermost(r).publish(getCommitList(r), expandedCustomMessage, getBuildColor(r));
}
}
}
public void completed(AbstractBuild r) {
AbstractProject<?, ?> project = r.getProject();
Result result = r.getResult();
AbstractBuild<?, ?> previousBuild = project.getLastBuild();
if (previousBuild != null) {
do {
previousBuild = previousBuild.getPreviousCompletedBuild();
} while (previousBuild != null && previousBuild.getResult() == Result.ABORTED);
}
Result previousResult = (previousBuild != null) ? previousBuild.getResult() : Result.SUCCESS;
if ((result == Result.ABORTED && notifier.getNotifyAborted())
|| (result == Result.FAILURE // notify only on
// single failed
// build
&& previousResult != Result.FAILURE
&& notifier.getNotifyFailure())
|| (result == Result.FAILURE // notify only on repeated failures
&& previousResult == Result.FAILURE
&& notifier.getNotifyRepeatedFailure())
|| (result == Result.NOT_BUILT && notifier.getNotifyNotBuilt())
|| (result == Result.SUCCESS
&& (previousResult == Result.FAILURE || previousResult == Result.UNSTABLE)
&& notifier.getNotifyBackToNormal())
|| (result == Result.SUCCESS && notifier.getNotifySuccess())
|| (result == Result.UNSTABLE && notifier.getNotifyUnstable())) {
String expandedCustomMessage = getExpandedCustomMessage(r);
getMattermost(r)
.publish(
getBuildStatusMessage(
r,
notifier.getIncludeTestSummary(),
notifier.getIncludeCustomAttachmentMessage()),
expandedCustomMessage,
getBuildColor(r));
if (notifier.getCommitInfoChoice().showAnything()) {
getMattermost(r).publish(getCommitList(r), expandedCustomMessage, getBuildColor(r));
}
}
}
String getChanges(AbstractBuild r, boolean includeCustomAttachmentMessage) {
if (!r.hasChangeSetComputed()) {
logger.info("No change set computed...");
return null;
}
ChangeLogSet changeSet = r.getChangeSet();
List<Entry> entries = new LinkedList<Entry>();
Set<AffectedFile> files = new HashSet<AffectedFile>();
for (Object o : changeSet.getItems()) {
Entry entry = (Entry)o;
logger.info("Entry " + o);
entries.add(entry);
files.addAll(entry.getAffectedFiles());
}
if (entries.isEmpty()) {
logger.info("Empty change...");
return null;
}
Set<String> authors = new HashSet<String>();
for (Entry entry : entries) {
authors.add(entry.getAuthor().getDisplayName());
}
MessageBuilder message = new MessageBuilder(notifier, r);
message.append(":pray: Started by changes from ");
message.append(StringUtils.join(authors, ", "));
message.append(" (");
message.append(files.size());
message.append(" file(s) changed)");
message.appendOpenLink();
if (includeCustomAttachmentMessage) {
message.appendCustomAttachmentMessage();
}
return message.toString();
}
String getChanges(AbstractBuild r, boolean includeCustomAttachmentMessage) {
if (!r.hasChangeSetComputed()) {
logger.info("No change set computed...");
return null;
}
ChangeLogSet changeSet = r.getChangeSet();
List<Entry> entries = new LinkedList<Entry>();
Set<AffectedFile> files = new HashSet<AffectedFile>();
for (Object o : changeSet.getItems()) {
Entry entry = (Entry) o;
logger.info("Entry " + o);
entries.add(entry);
files.addAll(entry.getAffectedFiles());
}
if (entries.isEmpty()) {
logger.info("Empty change...");
return null;
}
Set<String> authors = new HashSet<String>();
for (Entry entry : entries) {
authors.add(entry.getAuthor().getDisplayName());
}
MessageBuilder message = new MessageBuilder(notifier, r);
message.append(":pray: Started by changes from ");
message.append(StringUtils.join(authors, ", "));
message.append(" (");
message.append(files.size());
message.append(" file(s) changed)");
message.appendOpenLink();
if (includeCustomAttachmentMessage) {
message.appendCustomAttachmentMessage();
}
return message.toString();
}
String getCommitList(AbstractBuild r) {
ChangeLogSet changeSet = r.getChangeSet();
List<Entry> entries = new LinkedList<Entry>();
for (Object o : changeSet.getItems()) {
Entry entry = (Entry)o;
logger.info("Entry " + o);
entries.add(entry);
}
if (entries.isEmpty()) {
logger.info("Empty change...");
Cause.UpstreamCause c = (Cause.UpstreamCause)r.getCause(Cause.UpstreamCause.class);
if (c == null) {
return "No Changes.";
}
String upProjectName = c.getUpstreamProject();
int buildNumber = c.getUpstreamBuild();
AbstractProject project = Hudson.getInstance().getItemByFullName(upProjectName, AbstractProject.class);
if (project == null) {
return "No upstream project.";
}
AbstractBuild upBuild = (AbstractBuild)project.getBuildByNumber(buildNumber);
return getCommitList(upBuild);
}
Set<String> commits = new HashSet<String>();
for (Entry entry : entries) {
StringBuffer commit = new StringBuffer();
CommitInfoChoice commitInfoChoice = notifier.getCommitInfoChoice();
if (commitInfoChoice.showTitle()) {
commit.append(entry.getMsg());
}
if (commitInfoChoice.showAuthor()) {
commit.append(" [").append(entry.getAuthor().getDisplayName()).append("]");
}
commits.add(commit.toString());
}
MessageBuilder message = new MessageBuilder(notifier, r);
message.append("Changes:\n- ");
message.append(StringUtils.join(commits, "\n- "));
return message.toString();
}
String getCommitList(AbstractBuild r) {
ChangeLogSet changeSet = r.getChangeSet();
List<Entry> entries = new LinkedList<Entry>();
for (Object o : changeSet.getItems()) {
Entry entry = (Entry) o;
logger.info("Entry " + o);
entries.add(entry);
}
if (entries.isEmpty()) {
logger.info("Empty change...");
Cause.UpstreamCause c = (Cause.UpstreamCause) r.getCause(Cause.UpstreamCause.class);
if (c == null) {
return "No Changes.";
}
String upProjectName = c.getUpstreamProject();
int buildNumber = c.getUpstreamBuild();
AbstractProject project =
Hudson.getInstance().getItemByFullName(upProjectName, AbstractProject.class);
if (project == null) {
return "No upstream project.";
}
AbstractBuild upBuild = (AbstractBuild) project.getBuildByNumber(buildNumber);
return getCommitList(upBuild);
}
Set<String> commits = new HashSet<String>();
for (Entry entry : entries) {
StringBuffer commit = new StringBuffer();
CommitInfoChoice commitInfoChoice = notifier.getCommitInfoChoice();
if (commitInfoChoice.showTitle()) {
commit.append(entry.getMsg());
}
if (commitInfoChoice.showAuthor()) {
commit.append(" [").append(entry.getAuthor().getDisplayName()).append("]");
}
commits.add(commit.toString());
}
MessageBuilder message = new MessageBuilder(notifier, r);
message.append("Changes:\n- ");
message.append(StringUtils.join(commits, "\n- "));
return message.toString();
}
static String getBuildColor(AbstractBuild r) {
Result result = r.getResult();
if (result == Result.SUCCESS) {
return "good";
} else if (result == Result.FAILURE) {
return "danger";
} else {
return "warning";
}
}
static String getBuildColor(AbstractBuild r) {
Result result = r.getResult();
if (result == Result.SUCCESS) {
return "good";
} else if (result == Result.FAILURE) {
return "danger";
} else {
return "warning";
}
}
String getBuildStatusMessage(AbstractBuild r, boolean includeTestSummary, boolean includeCustomAttachmentMessage) {
MessageBuilder message = new MessageBuilder(notifier, r);
message.appendStatusMessage();
message.appendDuration();
message.appendOpenLink();
if (includeTestSummary) {
message.appendTestSummary();
}
if (includeCustomAttachmentMessage) {
message.appendCustomAttachmentMessage();
}
return message.toString();
}
String getBuildStatusMessage(
AbstractBuild r, boolean includeTestSummary, boolean includeCustomAttachmentMessage) {
MessageBuilder message = new MessageBuilder(notifier, r);
message.appendStatusMessage();
message.appendDuration();
message.appendOpenLink();
if (includeTestSummary) {
message.appendTestSummary();
}
if (includeCustomAttachmentMessage) {
message.appendCustomAttachmentMessage();
}
return message.toString();
}
String getExpandedCustomMessage(AbstractBuild build) {
String result = "";
if(notifier.getIncludeCustomMessage()) {
String customMessage = notifier.getCustomMessage();
EnvVars envVars = new EnvVars();
try {
envVars = build.getEnvironment(new LogTaskListener(logger, INFO));
} catch (IOException | InterruptedException e) {
logger.log(SEVERE, e.getMessage(), e);
}
result = envVars.expand(customMessage);
}
return result;
}
String getExpandedCustomMessage(AbstractBuild build) {
String result = "";
if (notifier.getIncludeCustomMessage()) {
String customMessage = notifier.getCustomMessage();
EnvVars envVars = new EnvVars();
try {
envVars = build.getEnvironment(new LogTaskListener(logger, INFO));
} catch (IOException | InterruptedException e) {
logger.log(SEVERE, e.getMessage(), e);
}
result = envVars.expand(customMessage);
}
return result;
}
public static class MessageBuilder {
public static class MessageBuilder {
private static final String STARTING_STATUS_MESSAGE = ":pray: Starting...",
BACK_TO_NORMAL_STATUS_MESSAGE = ":white_check_mark: Back to normal",
STILL_FAILING_STATUS_MESSAGE = ":no_entry_sign: Still Failing",
SUCCESS_STATUS_MESSAGE = ":white_check_mark: Success",
FAILURE_STATUS_MESSAGE = ":no_entry_sign: Failure",
ABORTED_STATUS_MESSAGE = ":warning: Aborted",
NOT_BUILT_STATUS_MESSAGE = ":warning: Not built",
UNSTABLE_STATUS_MESSAGE = ":warning: Unstable",
UNKNOWN_STATUS_MESSAGE = ":question: Unknown";
private static final String STARTING_STATUS_MESSAGE = ":pray: Starting...",
BACK_TO_NORMAL_STATUS_MESSAGE = ":white_check_mark: Back to normal",
STILL_FAILING_STATUS_MESSAGE = ":no_entry_sign: Still Failing",
SUCCESS_STATUS_MESSAGE = ":white_check_mark: Success",
FAILURE_STATUS_MESSAGE = ":no_entry_sign: Failure",
ABORTED_STATUS_MESSAGE = ":warning: Aborted",
NOT_BUILT_STATUS_MESSAGE = ":warning: Not built",
UNSTABLE_STATUS_MESSAGE = ":warning: Unstable",
UNKNOWN_STATUS_MESSAGE = ":question: Unknown";
private StringBuffer message;
private MattermostNotifier notifier;
private AbstractBuild build;
private StringBuffer message;
private MattermostNotifier notifier;
private AbstractBuild build;
public MessageBuilder(MattermostNotifier notifier, AbstractBuild build) {
this.notifier = notifier;
this.message = new StringBuffer();
this.build = build;
startMessage();
}
public MessageBuilder(MattermostNotifier notifier, AbstractBuild build) {
this.notifier = notifier;
this.message = new StringBuffer();
this.build = build;
startMessage();
}
public MessageBuilder appendStatusMessage() {
message.append(this.escape(getStatusMessage(build)));
return this;
}
public MessageBuilder appendStatusMessage() {
message.append(this.escape(getStatusMessage(build)));
return this;
}
static String getStatusMessage(AbstractBuild r) {
if (r.isBuilding()) {
return STARTING_STATUS_MESSAGE;
}
Result result = r.getResult();
Result previousResult;
Run lastBuild = r.getProject().getLastBuild();
Run previousBuild = (lastBuild != null) ? lastBuild.getPreviousBuild() : null;
Run previousSuccessfulBuild = r.getPreviousSuccessfulBuild();
boolean buildHasSucceededBefore = previousSuccessfulBuild != null;
static String getStatusMessage(AbstractBuild r) {
if (r.isBuilding()) {
return STARTING_STATUS_MESSAGE;
}
Result result = r.getResult();
Result previousResult;
Run lastBuild = r.getProject().getLastBuild();
Run previousBuild = (lastBuild != null) ? lastBuild.getPreviousBuild() : null;
Run previousSuccessfulBuild = r.getPreviousSuccessfulBuild();
boolean buildHasSucceededBefore = previousSuccessfulBuild != null;
/*
* If the last build was aborted, go back to find the last non-aborted build.
* This is so that aborted builds do not affect build transitions.
* I.e. if build 1 was failure, build 2 was aborted and build 3 was a success the transition
* should be failure -> success (and therefore back to normal) not aborted -> success.
*/
Run lastNonAbortedBuild = previousBuild;
while (lastNonAbortedBuild != null && lastNonAbortedBuild.getResult() == Result.ABORTED) {
lastNonAbortedBuild = lastNonAbortedBuild.getPreviousBuild();
}
/*
* If the last build was aborted, go back to find the last non-aborted build.
* This is so that aborted builds do not affect build transitions. I.e. if build
* 1 was failure, build 2 was aborted and build 3 was a success the transition
* should be failure -> success (and therefore back to normal) not aborted ->
* success.
*/
Run lastNonAbortedBuild = previousBuild;
while (lastNonAbortedBuild != null && lastNonAbortedBuild.getResult() == Result.ABORTED) {
lastNonAbortedBuild = lastNonAbortedBuild.getPreviousBuild();
}
/*
* If all previous builds have been aborted, then use SUCCESS as a default
* status so an aborted message is sent
*/
if (lastNonAbortedBuild == null) {
previousResult = Result.SUCCESS;
} else {
previousResult = lastNonAbortedBuild.getResult();
}
/* If all previous builds have been aborted, then use
* SUCCESS as a default status so an aborted message is sent
*/
if (lastNonAbortedBuild == null) {
previousResult = Result.SUCCESS;
} else {
previousResult = lastNonAbortedBuild.getResult();
}
/*
* Back to normal should only be shown if the build has actually succeeded at
* some point. Also, if a build was previously unstable and has now succeeded
* the status should be "Back to normal"
*/
if (result == Result.SUCCESS
&& (previousResult == Result.FAILURE || previousResult == Result.UNSTABLE)
&& buildHasSucceededBefore) {
return BACK_TO_NORMAL_STATUS_MESSAGE;
}
if (result == Result.FAILURE && previousResult == Result.FAILURE) {
return STILL_FAILING_STATUS_MESSAGE;
}
if (result == Result.SUCCESS) {
return SUCCESS_STATUS_MESSAGE;
}
if (result == Result.FAILURE) {
return FAILURE_STATUS_MESSAGE;
}
if (result == Result.ABORTED) {
return ABORTED_STATUS_MESSAGE;
}
if (result == Result.NOT_BUILT) {
return NOT_BUILT_STATUS_MESSAGE;
}
if (result == Result.UNSTABLE) {
return UNSTABLE_STATUS_MESSAGE;
}
return UNKNOWN_STATUS_MESSAGE;
}
/* Back to normal should only be shown if the build has actually succeeded at some point.
* Also, if a build was previously unstable and has now succeeded the status should be
* "Back to normal"
*/
if (result == Result.SUCCESS
&& (previousResult == Result.FAILURE || previousResult == Result.UNSTABLE)
&& buildHasSucceededBefore) {
return BACK_TO_NORMAL_STATUS_MESSAGE;
}
if (result == Result.FAILURE && previousResult == Result.FAILURE) {
return STILL_FAILING_STATUS_MESSAGE;
}
if (result == Result.SUCCESS) {
return SUCCESS_STATUS_MESSAGE;
}
if (result == Result.FAILURE) {
return FAILURE_STATUS_MESSAGE;
}
if (result == Result.ABORTED) {
return ABORTED_STATUS_MESSAGE;
}
if (result == Result.NOT_BUILT) {
return NOT_BUILT_STATUS_MESSAGE;
}
if (result == Result.UNSTABLE) {
return UNSTABLE_STATUS_MESSAGE;
}
return UNKNOWN_STATUS_MESSAGE;
}
public MessageBuilder append(String string) {
message.append(this.escape(string));
return this;
}
public MessageBuilder append(String string) {
message.append(this.escape(string));
return this;
}
public MessageBuilder append(Object string) {
message.append(this.escape(string.toString()));
return this;
}
public MessageBuilder append(Object string) {
message.append(this.escape(string.toString()));
return this;
}
private MessageBuilder startMessage() {
message.append(this.escapeDisplayName(build.getProject().getFullDisplayName()));
message.append(" - ");
message.append(this.escapeDisplayName(build.getDisplayName()));
message.append(" ");
return this;
}
private MessageBuilder startMessage() {
message.append(this.escapeDisplayName(build.getProject().getFullDisplayName()));
message.append(" - ");
message.append(this.escapeDisplayName(build.getDisplayName()));
message.append(" ");
return this;
}
public MessageBuilder appendOpenLink() {
String url = notifier.getBuildServerUrl() + build.getUrl();
message.append(" [Open](").append(url).append(")");
return this;
}
public MessageBuilder appendOpenLink() {
String url = notifier.getBuildServerUrl() + build.getUrl();
message.append(" [Open](").append(url).append(")");
return this;
}
public MessageBuilder appendDuration() {
message.append(" after ");
String durationString;
if (message.toString().contains(BACK_TO_NORMAL_STATUS_MESSAGE)) {
durationString = createBackToNormalDurationString();
} else {
durationString = build.getDurationString();
}
message.append(durationString);
return this;
}
public MessageBuilder appendDuration() {
message.append(" after ");
String durationString;
if (message.toString().contains(BACK_TO_NORMAL_STATUS_MESSAGE)) {
durationString = createBackToNormalDurationString();
} else {
durationString = build.getDurationString();
}
message.append(durationString);
return this;
}
public MessageBuilder appendTestSummary() {
AbstractTestResultAction<?> action = this.build.getAction(AbstractTestResultAction.class);
if (action != null) {
int total = action.getTotalCount();
int failed = action.getFailCount();
int skipped = action.getSkipCount();
message.append("\nTest Status:\n");
message.append("\tPassed: " + (total - failed - skipped));
message.append(", Failed: " + failed);
message.append(", Skipped: " + skipped);
} else {
message.append("\nNo Tests found.");
}
return this;
}
public MessageBuilder appendTestSummary() {
AbstractTestResultAction<?> action = this.build
.getAction(AbstractTestResultAction.class);
if (action != null) {
int total = action.getTotalCount();
int failed = action.getFailCount();
int skipped = action.getSkipCount();
message.append("\nTest Status:\n");
message.append("\tPassed: " + (total - failed - skipped));
message.append(", Failed: " + failed);
message.append(", Skipped: " + skipped);
} else {
message.append("\nNo Tests found.");
}
return this;
}
public MessageBuilder appendCustomAttachmentMessage() {
String customAttachmentMessage = notifier.getCustomAttachmentMessage();
EnvVars envVars = new EnvVars();
try {
envVars = build.getEnvironment(new LogTaskListener(logger, INFO));
} catch (IOException e) {
logger.log(SEVERE, e.getMessage(), e);
} catch (InterruptedException e) {
logger.log(SEVERE, e.getMessage(), e);
}
message.append("\n");
message.append(envVars.expand(customAttachmentMessage));
return this;
}
public MessageBuilder appendCustomAttachmentMessage() {
String customAttachmentMessage = notifier.getCustomAttachmentMessage();
EnvVars envVars = new EnvVars();
try {
envVars = build.getEnvironment(new LogTaskListener(logger, INFO));
} catch (IOException e) {
logger.log(SEVERE, e.getMessage(), e);
} catch (InterruptedException e) {
logger.log(SEVERE, e.getMessage(), e);
}
message.append("\n");
message.append(envVars.expand(customAttachmentMessage));
return this;
}
private String createBackToNormalDurationString() {
Run previousSuccessfulBuild = build.getPreviousSuccessfulBuild();
if (previousSuccessfulBuild == null) {
return "unknown";
}
long previousSuccessStartTime = previousSuccessfulBuild.getStartTimeInMillis();
long previousSuccessDuration = previousSuccessfulBuild.getDuration();
long previousSuccessEndTime = previousSuccessStartTime + previousSuccessDuration;
long buildStartTime = build.getStartTimeInMillis();
long buildDuration = build.getDuration();
long buildEndTime = buildStartTime + buildDuration;
long backToNormalDuration = buildEndTime - previousSuccessEndTime;
return Util.getTimeSpanString(backToNormalDuration);
}
private String createBackToNormalDurationString() {
Run previousSuccessfulBuild = build.getPreviousSuccessfulBuild();
if (previousSuccessfulBuild == null) {
return "unknown";
}
long previousSuccessStartTime = previousSuccessfulBuild.getStartTimeInMillis();
long previousSuccessDuration = previousSuccessfulBuild.getDuration();
long previousSuccessEndTime = previousSuccessStartTime + previousSuccessDuration;
long buildStartTime = build.getStartTimeInMillis();
long buildDuration = build.getDuration();
long buildEndTime = buildStartTime + buildDuration;
long backToNormalDuration = buildEndTime - previousSuccessEndTime;
return Util.getTimeSpanString(backToNormalDuration);
}
public String escape(String string) {
string = string.replace("&", "&amp;");
string = string.replace("<", "&lt;");
string = string.replace(">", "&gt;");
public String escape(String string) {
string = string.replace("&", "&amp;");
string = string.replace("<", "&lt;");
string = string.replace(">", "&gt;");
return string;
}
return string;
}
public String escapeDisplayName(String displayName) {
// escape HTML
displayName = escape(displayName);
public String escapeDisplayName(String displayName) {
// escape HTML
displayName = escape(displayName);
// escape mattermost markdown which _may_ occur in job display names
displayName = displayName.replace("~", "\\~");
displayName = displayName.replace("*", "\\*");
displayName = displayName.replace("_", "\\_");
displayName = displayName.replace("`", "\\`");
// escape mattermost markdown which _may_ occur in job display names
displayName = displayName.replace("~", "\\~");
displayName = displayName.replace("*", "\\*");
displayName = displayName.replace("_", "\\_");
displayName = displayName.replace("`", "\\`");
return displayName;
}
return displayName;
}
public String toString() {
return message.toString();
}
}
public String toString() {
return message.toString();
}
}
}

View File

@ -1,40 +1,42 @@
package jenkins.plugins.mattermost;
public enum CommitInfoChoice {
NONE("nothing about commits", false, false),
AUTHORS("commit list with authors only", true, false),
AUTHORS_AND_TITLES("commit list with authors and titles", true, true);
NONE("nothing about commits", false, false),
AUTHORS("commit list with authors only", true, false),
AUTHORS_AND_TITLES("commit list with authors and titles", true, true);
private final String displayName;
private boolean showAuthor;
private boolean showTitle;
private final String displayName;
private boolean showAuthor;
private boolean showTitle;
private CommitInfoChoice(String displayName, boolean showAuthor, boolean showTitle) {
this.displayName = displayName;
this.showAuthor = showAuthor;
this.showTitle = showTitle;
}
private CommitInfoChoice(String displayName, boolean showAuthor, boolean showTitle) {
this.displayName = displayName;
this.showAuthor = showAuthor;
this.showTitle = showTitle;
}
public boolean showAuthor() {
return this.showAuthor;
}
public boolean showTitle() {
return this.showTitle;
}
public boolean showAnything() {
return showAuthor() || showTitle();
}
public boolean showAuthor() {
return this.showAuthor;
}
public String getDisplayName() {
return this.displayName;
}
public boolean showTitle() {
return this.showTitle;
}
public static CommitInfoChoice forDisplayName(String displayName) {
for (CommitInfoChoice commitInfoChoice : values()) {
if (commitInfoChoice.getDisplayName().equals(displayName)) {
return commitInfoChoice;
}
}
return null;
public boolean showAnything() {
return showAuthor() || showTitle();
}
public String getDisplayName() {
return this.displayName;
}
public static CommitInfoChoice forDisplayName(String displayName) {
for (CommitInfoChoice commitInfoChoice : values()) {
if (commitInfoChoice.getDisplayName().equals(displayName)) {
return commitInfoChoice;
}
}
return null;
}
}

View File

@ -4,15 +4,11 @@ import hudson.model.AbstractBuild;
@SuppressWarnings("rawtypes")
public class DisabledNotifier implements FineGrainedNotifier {
public void started(AbstractBuild r) {
}
public void started(AbstractBuild r) {}
public void deleted(AbstractBuild r) {
}
public void deleted(AbstractBuild r) {}
public void finalized(AbstractBuild r) {
}
public void finalized(AbstractBuild r) {}
public void completed(AbstractBuild r) {
}
public void completed(AbstractBuild r) {}
}

View File

@ -4,16 +4,15 @@ import hudson.model.AbstractBuild;
public interface FineGrainedNotifier {
@SuppressWarnings("rawtypes")
void started(AbstractBuild r);
@SuppressWarnings("rawtypes")
void started(AbstractBuild r);
@SuppressWarnings("rawtypes")
void deleted(AbstractBuild r);
@SuppressWarnings("rawtypes")
void deleted(AbstractBuild r);
@SuppressWarnings("rawtypes")
void finalized(AbstractBuild r);
@SuppressWarnings("rawtypes")
void completed(AbstractBuild r);
@SuppressWarnings("rawtypes")
void finalized(AbstractBuild r);
@SuppressWarnings("rawtypes")
void completed(AbstractBuild r);
}

View File

@ -8,7 +8,6 @@ import hudson.model.Descriptor;
import hudson.model.TaskListener;
import hudson.model.listeners.RunListener;
import hudson.tasks.Publisher;
import java.util.Map;
import java.util.logging.Logger;
@ -16,45 +15,44 @@ import java.util.logging.Logger;
@SuppressWarnings("rawtypes")
public class MattermostListener extends RunListener<AbstractBuild> {
private static final Logger logger = Logger.getLogger(MattermostListener.class.getName());
private static final Logger logger = Logger.getLogger(MattermostListener.class.getName());
public MattermostListener() {
super(AbstractBuild.class);
}
public MattermostListener() {
super(AbstractBuild.class);
}
@Override
public void onCompleted(AbstractBuild r, TaskListener listener) {
getNotifier(r.getProject(), listener).completed(r);
super.onCompleted(r, listener);
}
@Override
public void onCompleted(AbstractBuild r, TaskListener listener) {
getNotifier(r.getProject(), listener).completed(r);
super.onCompleted(r, listener);
}
@Override
public void onStarted(AbstractBuild r, TaskListener listener) {
// getNotifier(r.getProject()).started(r);
// super.onStarted(r, listener);
}
@Override
public void onStarted(AbstractBuild r, TaskListener listener) {
// getNotifier(r.getProject()).started(r);
// super.onStarted(r, listener);
}
@Override
public void onDeleted(AbstractBuild r) {
// getNotifier(r.getProject()).deleted(r);
// super.onDeleted(r);
}
@Override
public void onDeleted(AbstractBuild r) {
// getNotifier(r.getProject()).deleted(r);
// super.onDeleted(r);
}
@Override
public void onFinalized(AbstractBuild r) {
// getNotifier(r.getProject()).finalized(r);
// super.onFinalized(r);
}
@SuppressWarnings("unchecked")
FineGrainedNotifier getNotifier(AbstractProject project, TaskListener listener) {
Map<Descriptor<Publisher>, Publisher> map = project.getPublishersList().toMap();
for (Publisher publisher : map.values()) {
if (publisher instanceof MattermostNotifier) {
return new ActiveNotifier((MattermostNotifier) publisher, (BuildListener)listener);
}
}
return new DisabledNotifier();
}
@Override
public void onFinalized(AbstractBuild r) {
// getNotifier(r.getProject()).finalized(r);
// super.onFinalized(r);
}
@SuppressWarnings("unchecked")
FineGrainedNotifier getNotifier(AbstractProject project, TaskListener listener) {
Map<Descriptor<Publisher>, Publisher> map = project.getPublishersList().toMap();
for (Publisher publisher : map.values()) {
if (publisher instanceof MattermostNotifier) {
return new ActiveNotifier((MattermostNotifier) publisher, (BuildListener) listener);
}
}
return new DisabledNotifier();
}
}

View File

@ -1,10 +1,6 @@
package jenkins.plugins.mattermost;
import javax.annotation.CheckForNull;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static hudson.Util.fixNull;
import hudson.EnvVars;
import hudson.Extension;
@ -21,6 +17,11 @@ import hudson.tasks.Publisher;
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import hudson.util.Secret;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.CheckForNull;
import jenkins.model.Jenkins;
import jenkins.model.JenkinsLocationConfiguration;
import net.sf.json.JSONObject;
@ -33,9 +34,6 @@ import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.verb.POST;
import static hudson.Util.fixNull;
public class MattermostNotifier extends Notifier {
private static final Logger logger = Logger.getLogger(MattermostNotifier.class.getName());
@ -54,7 +52,7 @@ public class MattermostNotifier extends Notifier {
private boolean notifyBackToNormal;
private boolean notifyRepeatedFailure;
private boolean includeTestSummary;
transient private boolean showCommitList;
private transient boolean showCommitList;
private CommitInfoChoice commitInfoChoice;
private boolean includeCustomAttachmentMessage;
private String customAttachmentMessage;
@ -63,7 +61,7 @@ public class MattermostNotifier extends Notifier {
@Override
public DescriptorImpl getDescriptor() {
return (DescriptorImpl)super.getDescriptor();
return (DescriptorImpl) super.getDescriptor();
}
public Secret getEndpoint() {
@ -244,11 +242,26 @@ public class MattermostNotifier extends Notifier {
}
@DataBoundConstructor
public MattermostNotifier(final Secret endpoint, final String room, final String icon, final String buildServerUrl,
final String sendAs, final boolean startNotification, final boolean notifyAborted, final boolean notifyFailure,
final boolean notifyNotBuilt, final boolean notifySuccess, final boolean notifyUnstable, final boolean notifyBackToNormal,
final boolean notifyRepeatedFailure, final boolean includeTestSummary, CommitInfoChoice commitInfoChoice,
boolean includeCustomAttachmentMessage, String customAttachmentMessage, final boolean includeCustomMessage, final String customMessage) {
public MattermostNotifier(
final Secret endpoint,
final String room,
final String icon,
final String buildServerUrl,
final String sendAs,
final boolean startNotification,
final boolean notifyAborted,
final boolean notifyFailure,
final boolean notifyNotBuilt,
final boolean notifySuccess,
final boolean notifyUnstable,
final boolean notifyBackToNormal,
final boolean notifyRepeatedFailure,
final boolean includeTestSummary,
CommitInfoChoice commitInfoChoice,
boolean includeCustomAttachmentMessage,
String customAttachmentMessage,
final boolean includeCustomMessage,
final String customMessage) {
super();
this.endpoint = endpoint;
this.buildServerUrl = buildServerUrl;
@ -266,14 +279,14 @@ public class MattermostNotifier extends Notifier {
this.includeTestSummary = includeTestSummary;
this.commitInfoChoice = commitInfoChoice;
this.includeCustomAttachmentMessage = includeCustomAttachmentMessage;
if(includeCustomAttachmentMessage) {
if (includeCustomAttachmentMessage) {
this.customAttachmentMessage = customAttachmentMessage;
} else {
this.customAttachmentMessage = null;
}
this.includeCustomMessage = includeCustomMessage;
if(includeCustomMessage) {
if (includeCustomMessage) {
this.customMessage = customMessage;
} else {
this.customMessage = null;
@ -314,7 +327,8 @@ public class MattermostNotifier extends Notifier {
}
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener)
throws InterruptedException, IOException {
return true;
}
@ -325,14 +339,15 @@ public class MattermostNotifier extends Notifier {
for (Publisher publisher : map.values()) {
if (publisher instanceof MattermostNotifier) {
logger.info("Invoking Started...");
new ActiveNotifier((MattermostNotifier)publisher, listener).started(build);
new ActiveNotifier((MattermostNotifier) publisher, listener).started(build);
}
}
}
return super.prebuild(build, listener);
}
@Extension @Symbol("mattermostNotifier")
@Extension
@Symbol("mattermostNotifier")
public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
private Secret endpoint;
@ -419,7 +434,8 @@ public class MattermostNotifier extends Notifier {
return true;
}
MattermostService getMattermostService(final String endpoint, final String room, final String icon) {
MattermostService getMattermostService(
final String endpoint, final String room, final String icon) {
return new StandardMattermostService(endpoint, room, icon);
}
@ -429,47 +445,57 @@ public class MattermostNotifier extends Notifier {
}
@POST
public FormValidation doTestConnection(@QueryParameter("endpoint") final String endpoint,
public FormValidation doTestConnection(
@QueryParameter("endpoint") final String endpoint,
@QueryParameter("room") final String room,
@QueryParameter("icon") final String icon,
@QueryParameter("buildServerUrl") final String buildServerUrl) throws FormException {
if (!Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) {
return FormValidation.error("Insufficient permission.");
@QueryParameter("buildServerUrl") final String buildServerUrl)
throws FormException {
if (!Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) {
return FormValidation.error("Insufficient permission.");
}
try {
String targetEndpoint = endpoint;
if (StringUtils.isEmpty(targetEndpoint)) {
targetEndpoint = Secret.toString(this.getEndpoint());
}
try {
String targetEndpoint = endpoint;
if (StringUtils.isEmpty(targetEndpoint)) {
targetEndpoint = Secret.toString(this.getEndpoint());
}
String targetRoom = room;
if (StringUtils.isEmpty(targetRoom)) {
targetRoom = this.room;
}
String targetIcon = icon;
if (StringUtils.isEmpty(targetIcon)) {
targetIcon = this.icon;
}
String targetBuildServerUrl = buildServerUrl;
if (StringUtils.isEmpty(targetBuildServerUrl)) {
targetBuildServerUrl = this.buildServerUrl;
}
MattermostService testMattermostService = getMattermostService(targetEndpoint, targetRoom, targetIcon);
String message = "Mattermost/Jenkins plugin: you're all set! (parameters: " +
"room='" + targetRoom + "', " +
"icon='" + targetIcon + "', " +
"buildServerUrl='" + targetBuildServerUrl + "'" +
")";
boolean success = testMattermostService.publish(message, "good");
return success ? FormValidation.ok("Success") : FormValidation.error("Failure");
} catch (Exception e) {
return FormValidation.error("Client error : " + e.getMessage());
String targetRoom = room;
if (StringUtils.isEmpty(targetRoom)) {
targetRoom = this.room;
}
String targetIcon = icon;
if (StringUtils.isEmpty(targetIcon)) {
targetIcon = this.icon;
}
String targetBuildServerUrl = buildServerUrl;
if (StringUtils.isEmpty(targetBuildServerUrl)) {
targetBuildServerUrl = this.buildServerUrl;
}
MattermostService testMattermostService =
getMattermostService(targetEndpoint, targetRoom, targetIcon);
String message =
"Mattermost/Jenkins plugin: you're all set! (parameters: "
+ "room='"
+ targetRoom
+ "', "
+ "icon='"
+ targetIcon
+ "', "
+ "buildServerUrl='"
+ targetBuildServerUrl
+ "'"
+ ")";
boolean success = testMattermostService.publish(message, "good");
return success ? FormValidation.ok("Success") : FormValidation.error("Failure");
} catch (Exception e) {
return FormValidation.error("Client error : " + e.getMessage());
}
}
}
@Deprecated
public static class MattermostJobProperty extends hudson.model.JobProperty<AbstractProject<?, ?>> {
public static class MattermostJobProperty
extends hudson.model.JobProperty<AbstractProject<?, ?>> {
private String endpoint;
private String room;
@ -490,7 +516,8 @@ public class MattermostNotifier extends Notifier {
private boolean includeCustomMessage;
@DataBoundConstructor
public MattermostJobProperty(String teamDomain,
public MattermostJobProperty(
String teamDomain,
String room,
String icon,
boolean startNotification,
@ -617,7 +644,6 @@ public class MattermostNotifier extends Notifier {
}
}
@Extension
public static final class Migrator extends ItemListener {
@ -626,24 +652,27 @@ public class MattermostNotifier extends Notifier {
public void onLoaded() {
logger.info("Starting Settings Migration Process");
for (AbstractProject<?, ?> p : Jenkins.getInstance().getAllItems(AbstractProject.class)) {
final MattermostJobProperty mattermostJobProperty = p.getProperty(MattermostJobProperty.class);
final MattermostJobProperty mattermostJobProperty =
p.getProperty(MattermostJobProperty.class);
if (mattermostJobProperty == null) {
logger.fine(String
.format("Configuration is already up to date for \"%s\", skipping migration",
p.getName()));
logger.fine(
String.format(
"Configuration is already up to date for \"%s\", skipping migration",
p.getName()));
continue;
}
MattermostNotifier mattermostNotifier = p.getPublishersList().get(MattermostNotifier.class);
if (mattermostNotifier == null) {
logger.fine(String
.format("Configuration does not have a notifier for \"%s\", not migrating settings",
p.getName()));
logger.fine(
String.format(
"Configuration does not have a notifier for \"%s\", not migrating settings",
p.getName()));
} else {
logger.info(String.format("Starting migration for \"%s\"", p.getName()));
//map settings
// map settings
if (StringUtils.isBlank(Secret.toString(mattermostNotifier.getEndpoint()))) {
mattermostNotifier.setEndpoint(mattermostJobProperty.getEndpoint());
}
@ -662,18 +691,24 @@ public class MattermostNotifier extends Notifier {
mattermostNotifier.notifySuccess = mattermostJobProperty.getNotifySuccess();
mattermostNotifier.notifyUnstable = mattermostJobProperty.getNotifyUnstable();
mattermostNotifier.notifyBackToNormal = mattermostJobProperty.getNotifyBackToNormal();
mattermostNotifier.notifyRepeatedFailure = mattermostJobProperty.getNotifyRepeatedFailure();
mattermostNotifier.notifyRepeatedFailure =
mattermostJobProperty.getNotifyRepeatedFailure();
mattermostNotifier.includeTestSummary = mattermostJobProperty.includeTestSummary();
mattermostNotifier.commitInfoChoice = mattermostJobProperty.getShowCommitList() ? CommitInfoChoice.AUTHORS_AND_TITLES : CommitInfoChoice.NONE;
mattermostNotifier.includeCustomAttachmentMessage = mattermostJobProperty.includeCustomAttachmentMessage();
mattermostNotifier.customAttachmentMessage = mattermostJobProperty.getCustomAttachmentMessage();
mattermostNotifier.commitInfoChoice =
mattermostJobProperty.getShowCommitList()
? CommitInfoChoice.AUTHORS_AND_TITLES
: CommitInfoChoice.NONE;
mattermostNotifier.includeCustomAttachmentMessage =
mattermostJobProperty.includeCustomAttachmentMessage();
mattermostNotifier.customAttachmentMessage =
mattermostJobProperty.getCustomAttachmentMessage();
mattermostNotifier.includeCustomMessage = mattermostJobProperty.includeCustomMessage();
mattermostNotifier.customMessage = mattermostJobProperty.getCustomMessage();
}
try {
//property section is not used anymore - remove
// property section is not used anymore - remove
p.removeProperty(MattermostJobProperty.class);
p.save();
logger.info("Configuration updated successfully");

View File

@ -1,9 +1,9 @@
package jenkins.plugins.mattermost;
public interface MattermostService {
boolean publish(String message);
boolean publish(String message);
boolean publish(String message, String color);
boolean publish(String message, String color);
boolean publish(String message, String text, String color);
boolean publish(String message, String text, String color);
}

View File

@ -1,6 +1,12 @@
package jenkins.plugins.mattermost;
import hudson.ProxyConfiguration;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import jenkins.model.Jenkins;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
@ -8,151 +14,147 @@ import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang.StringUtils;
import org.json.JSONObject;
import org.json.JSONArray;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.json.JSONObject;
public class StandardMattermostService implements MattermostService {
private static final Logger logger = Logger.getLogger(StandardMattermostService.class.getName());
private static final Logger logger = Logger.getLogger(StandardMattermostService.class.getName());
private String endpoint;
private String[] roomIds;
private String icon;
private String endpoint;
private String[] roomIds;
private String icon;
public StandardMattermostService(String endpoint, String roomId, String icon) {
super();
this.endpoint = endpoint;
this.roomIds = roomId.split("[,;]+");
this.icon = icon;
}
public StandardMattermostService(String endpoint, String roomId, String icon) {
super();
this.endpoint = endpoint;
this.roomIds = roomId.split("[,;]+");
this.icon = icon;
}
public boolean publish(String message) {
return publish(message, "warning");
}
public boolean publish(String message) {
return publish(message, "warning");
}
public boolean publish(String message, String color) {
return publish(message, "", color);
}
public boolean publish(String message, String color) {
return publish(message, "", color);
}
public boolean publish(String message, String text, String color) {
boolean result = true;
for (String userAndRoomId : roomIds) {
String url = endpoint;
String roomId = userAndRoomId.trim();
String userId = "jenkins";
// Supported channel string formats:
// - user@channel
// - user@@dmchannel
// - channel
// - @dmchannel
int atPos = userAndRoomId.indexOf("@");
if (atPos > 0 && atPos < userAndRoomId.length() - 1) {
userId = userAndRoomId.substring(0, atPos).trim();
roomId = userAndRoomId.substring(atPos + 1).trim();
}
public boolean publish(String message, String text, String color) {
boolean result = true;
for (String userAndRoomId : roomIds) {
String url = endpoint;
String roomId = userAndRoomId.trim();
String userId = "jenkins";
// Supported channel string formats:
// - user@channel
// - user@@dmchannel
// - channel
// - @dmchannel
int atPos = userAndRoomId.indexOf("@");
if (atPos > 0 && atPos < userAndRoomId.length() - 1) {
userId = userAndRoomId.substring(0, atPos).trim();
roomId = userAndRoomId.substring(atPos + 1).trim();
}
String roomIdString = roomId;
String roomIdString = roomId;
if (StringUtils.isEmpty(roomIdString)) {
roomIdString = "(default)";
}
if (StringUtils.isEmpty(roomIdString)) {
roomIdString = "(default)";
}
logger.info("Posting: to " + roomIdString + "@" + url + ": " + message + " (" + color + ")");
HttpClient client = getHttpClient();
PostMethod post = new PostMethod(url);
JSONObject json = new JSONObject();
logger.info("Posting: to " + roomIdString + "@" + url + ": " + message + " (" + color + ")");
HttpClient client = getHttpClient();
PostMethod post = new PostMethod(url);
JSONObject json = new JSONObject();
try {
JSONObject field = new JSONObject();
field.put("short", false);
field.put("value", message);
JSONArray fields = new JSONArray();
fields.put(field);
try {
JSONObject field = new JSONObject();
field.put("short", false);
field.put("value", message);
JSONArray fields = new JSONArray();
fields.put(field);
JSONObject attachment = new JSONObject();
attachment.put("fallback", message);
attachment.put("color", color);
attachment.put("fields", fields);
JSONArray mrkdwn = new JSONArray();
mrkdwn.put("pretext");
mrkdwn.put("text");
mrkdwn.put("fields");
attachment.put("mrkdwn_in", mrkdwn);
JSONArray attachments = new JSONArray();
attachments.put(attachment);
json.put("text", text);
json.put("attachments", attachments);
JSONObject attachment = new JSONObject();
attachment.put("fallback", message);
attachment.put("color", color);
attachment.put("fields", fields);
JSONArray mrkdwn = new JSONArray();
mrkdwn.put("pretext");
mrkdwn.put("text");
mrkdwn.put("fields");
attachment.put("mrkdwn_in", mrkdwn);
JSONArray attachments = new JSONArray();
attachments.put(attachment);
json.put("text", text);
json.put("attachments", attachments);
if (!roomId.isEmpty()) json.put("channel", roomId);
json.put("username", userId);
json.put("icon_url", icon);
if (!roomId.isEmpty()) json.put("channel", roomId);
json.put("username", userId);
json.put("icon_url", icon);
post.addParameter("payload", json.toString());
post.getParams().setContentCharset("UTF-8");
int responseCode = client.executeMethod(post);
String response = post.getResponseBodyAsString();
if (responseCode != HttpStatus.SC_OK) {
logger.log(Level.WARNING, "Mattermost post may have failed. Response: " + response);
result = false;
}
} catch (Exception e) {
logger.log(Level.WARNING, "Error posting to Mattermost", e);
result = false;
} finally {
logger.info("Posting succeeded");
post.releaseConnection();
}
}
return result;
}
post.addParameter("payload", json.toString());
post.getParams().setContentCharset("UTF-8");
int responseCode = client.executeMethod(post);
String response = post.getResponseBodyAsString();
if (responseCode != HttpStatus.SC_OK) {
logger.log(Level.WARNING, "Mattermost post may have failed. Response: " + response);
result = false;
}
} catch (Exception e) {
logger.log(Level.WARNING, "Error posting to Mattermost", e);
result = false;
} finally {
logger.info("Posting succeeded");
post.releaseConnection();
}
}
return result;
}
protected HttpClient getHttpClient() {
HttpClient client = new HttpClient();
if (Jenkins.getInstance() != null) {
ProxyConfiguration proxy = Jenkins.getInstance().proxy;
if (proxy != null) {
if (isProxyRequired(proxy.getNoProxyHostPatterns())) {
client.getHostConfiguration().setProxy(proxy.name, proxy.port);
String username = proxy.getUserName();
String password = proxy.getPassword();
// Consider it to be passed if username specified. Sufficient?
if (username != null && !"".equals(username.trim())) {
logger.info("Using proxy authentication (user=" + username + ")");
// http://hc.apache.org/httpclient-3.x/authentication.html#Proxy_Authentication
// and
// http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/examples/BasicAuthenticationExample.java?view=markup
client.getState().setProxyCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(username, password));
}
}
}
}
return client;
}
protected HttpClient getHttpClient() {
HttpClient client = new HttpClient();
if (Jenkins.getInstance() != null) {
ProxyConfiguration proxy = Jenkins.getInstance().proxy;
if (proxy != null) {
if (isProxyRequired(proxy.getNoProxyHostPatterns())) {
client.getHostConfiguration().setProxy(proxy.name, proxy.port);
String username = proxy.getUserName();
String password = proxy.getPassword();
// Consider it to be passed if username specified. Sufficient?
if (username != null && !"".equals(username.trim())) {
logger.info("Using proxy authentication (user=" + username + ")");
// http://hc.apache.org/httpclient-3.x/authentication.html#Proxy_Authentication
// and
// http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/examples/BasicAuthenticationExample.java?view=markup
client
.getState()
.setProxyCredentials(
AuthScope.ANY, new UsernamePasswordCredentials(username, password));
}
}
}
}
return client;
}
protected boolean isProxyRequired(List<Pattern> noProxyHosts) {
try {
URL url = new URL(endpoint);
for (Pattern p : noProxyHosts) {
if (p.matcher(url.getHost()).matches())
return false;
}
} catch (MalformedURLException e) {
logger.log(Level.WARNING, "A malformed URL [" + endpoint + "] is defined as endpoint, please check your settings");
// default behavior : proxy still activated
return true;
}
return true;
}
protected boolean isProxyRequired(List<Pattern> noProxyHosts) {
try {
URL url = new URL(endpoint);
for (Pattern p : noProxyHosts) {
if (p.matcher(url.getHost()).matches()) return false;
}
} catch (MalformedURLException e) {
logger.log(
Level.WARNING,
"A malformed URL [" + endpoint + "] is defined as endpoint, please check your settings");
// default behavior : proxy still activated
return true;
}
return true;
}
void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
}

View File

@ -3,8 +3,10 @@ package jenkins.plugins.mattermost.workflow;
import hudson.AbortException;
import hudson.Extension;
import hudson.Util;
import hudson.util.Secret;
import hudson.model.TaskListener;
import hudson.util.Secret;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import jenkins.model.Jenkins;
import jenkins.plugins.mattermost.*;
import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
@ -14,153 +16,153 @@ import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import javax.annotation.Nonnull;
import javax.inject.Inject;
/**
* Workflow step to send a Mattermost channel notification.
*/
/** Workflow step to send a Mattermost channel notification. */
public class MattermostSendStep extends AbstractStepImpl {
private final @Nonnull String message;
private String text;
private String color;
private String channel;
private String endpoint;
private String icon;
private boolean failOnError;
private final @Nonnull String message;
private String text;
private String color;
private String channel;
private String endpoint;
private String icon;
private boolean failOnError;
@Nonnull
public String getMessage() {
return message;
}
@Nonnull
public String getMessage() {
return message;
public String getText() {
return text;
}
public String getColor() {
return color;
}
@DataBoundSetter
public void setText(String text) {
this.text = Util.fixEmpty(text);
}
@DataBoundSetter
public void setColor(String color) {
this.color = Util.fixEmpty(color);
}
public String getChannel() {
return channel;
}
@DataBoundSetter
public void setChannel(String channel) {
this.channel = Util.fixEmpty(channel);
}
public String getEndpoint() {
return endpoint;
}
@DataBoundSetter
public void setEndpoint(String endpoint) {
this.endpoint = Util.fixEmpty(endpoint);
}
public String getIcon() {
return icon;
}
@DataBoundSetter
public void setIcon(String icon) {
this.icon = Util.fixEmpty(icon);
}
public boolean isFailOnError() {
return failOnError;
}
@DataBoundSetter
public void setFailOnError(boolean failOnError) {
this.failOnError = failOnError;
}
@DataBoundConstructor
public MattermostSendStep(@Nonnull String message) {
this.message = message;
}
@Extension
public static class DescriptorImpl extends AbstractStepDescriptorImpl {
public DescriptorImpl() {
super(SlackSendStepExecution.class);
}
public String getText() {
return text;
@Override
public String getFunctionName() {
return "mattermostSend";
}
public String getColor() {
return color;
@Override
public String getDisplayName() {
return "Send Mattermost message";
}
}
public static class SlackSendStepExecution
extends AbstractSynchronousNonBlockingStepExecution<Void> {
private static final long serialVersionUID = 1L;
@Inject transient MattermostSendStep step;
@StepContextParameter transient TaskListener listener;
@Override
protected Void run() throws Exception {
// default to global config values if not set in step, but allow step to
// override all global settings
Jenkins jenkins;
// Jenkins.getInstance() may return null, no message sent in that case
try {
jenkins = Jenkins.getInstance();
} catch (NullPointerException ne) {
listener.error(String.format("Mattermost notification failed with exception: %s", ne), ne);
return null;
}
MattermostNotifier.DescriptorImpl mattermostDesc =
jenkins.getDescriptorByType(MattermostNotifier.DescriptorImpl.class);
String team =
step.getEndpoint() != null
? step.getEndpoint()
: Secret.toString(mattermostDesc.getEndpoint());
String channel = step.channel != null ? step.channel : mattermostDesc.getRoom();
String icon = step.icon != null ? step.icon : mattermostDesc.getIcon();
String color = step.color != null ? step.color : "";
String text = step.text != null ? step.text : "";
// placing in console log to simplify testing of retrieving values from global
// config or from step field; also used for tests
listener
.getLogger()
.printf(
"Mattermost Send Pipeline step configured values from global config - connector: %s, icon: %s, channel: %s, color: %s",
step.endpoint == null, step.icon == null, step.channel == null, step.color == null);
MattermostService mattermostService = getMattermostService(team, channel, icon);
boolean publishSuccess = mattermostService.publish(step.message, text, color);
if (!publishSuccess && step.failOnError) {
throw new AbortException("Mattermost notification failed. See Jenkins logs for details.");
} else if (!publishSuccess) {
listener.error("Mattermost notification failed. See Jenkins logs for details.");
}
return null;
}
@DataBoundSetter
public void setText(String text) {
this.text = Util.fixEmpty(text);
// streamline unit testing
MattermostService getMattermostService(String team, String channel, String icon) {
return new StandardMattermostService(team, channel, icon);
}
@DataBoundSetter
public void setColor(String color) {
this.color = Util.fixEmpty(color);
}
public String getChannel() {
return channel;
}
@DataBoundSetter
public void setChannel(String channel) {
this.channel = Util.fixEmpty(channel);
}
public String getEndpoint() {
return endpoint;
}
@DataBoundSetter
public void setEndpoint(String endpoint) {
this.endpoint = Util.fixEmpty(endpoint);
}
public String getIcon() {
return icon;
}
@DataBoundSetter
public void setIcon(String icon) {
this.icon = Util.fixEmpty(icon);
}
public boolean isFailOnError() {
return failOnError;
}
@DataBoundSetter
public void setFailOnError(boolean failOnError) {
this.failOnError = failOnError;
}
@DataBoundConstructor
public MattermostSendStep(@Nonnull String message) {
this.message = message;
}
@Extension
public static class DescriptorImpl extends AbstractStepDescriptorImpl {
public DescriptorImpl() {
super(SlackSendStepExecution.class);
}
@Override
public String getFunctionName() {
return "mattermostSend";
}
@Override
public String getDisplayName() {
return "Send Mattermost message";
}
}
public static class SlackSendStepExecution extends AbstractSynchronousNonBlockingStepExecution<Void> {
private static final long serialVersionUID = 1L;
@Inject
transient MattermostSendStep step;
@StepContextParameter
transient TaskListener listener;
@Override
protected Void run() throws Exception {
//default to global config values if not set in step, but allow step to override all global settings
Jenkins jenkins;
//Jenkins.getInstance() may return null, no message sent in that case
try {
jenkins = Jenkins.getInstance();
} catch (NullPointerException ne) {
listener.error(String.format("Mattermost notification failed with exception: %s", ne), ne);
return null;
}
MattermostNotifier.DescriptorImpl mattermostDesc = jenkins.getDescriptorByType(MattermostNotifier.DescriptorImpl.class);
String team = step.getEndpoint() != null ? step.getEndpoint() : Secret.toString(mattermostDesc.getEndpoint());
String channel = step.channel != null ? step.channel : mattermostDesc.getRoom();
String icon = step.icon != null ? step.icon : mattermostDesc.getIcon();
String color = step.color != null ? step.color : "";
String text = step.text != null ? step.text : "";
//placing in console log to simplify testing of retrieving values from global config or from step field; also used for tests
listener.getLogger().printf("Mattermost Send Pipeline step configured values from global config - connector: %s, icon: %s, channel: %s, color: %s", step.endpoint == null, step.icon == null, step.channel == null, step.color == null);
MattermostService mattermostService = getMattermostService(team, channel, icon);
boolean publishSuccess = mattermostService.publish(step.message, text, color);
if (!publishSuccess && step.failOnError) {
throw new AbortException("Mattermost notification failed. See Jenkins logs for details.");
} else if (!publishSuccess) {
listener.error("Mattermost notification failed. See Jenkins logs for details.");
}
return null;
}
//streamline unit testing
MattermostService getMattermostService(String team, String channel, String icon) {
return new StandardMattermostService(team, channel, icon);
}
}
}
}

View File

@ -6,29 +6,29 @@ import org.apache.commons.httpclient.HttpStatus;
public class HttpClientStub extends HttpClient {
private int numberOfCallsToExecuteMethod;
private int httpStatus;
private boolean failAlternateResponses = false;
private int numberOfCallsToExecuteMethod;
private int httpStatus;
private boolean failAlternateResponses = false;
@Override
public int executeMethod(HttpMethod httpMethod) {
numberOfCallsToExecuteMethod++;
if (failAlternateResponses && (numberOfCallsToExecuteMethod % 2 == 0)) {
return HttpStatus.SC_NOT_FOUND;
} else {
return httpStatus;
}
}
@Override
public int executeMethod(HttpMethod httpMethod) {
numberOfCallsToExecuteMethod++;
if (failAlternateResponses && (numberOfCallsToExecuteMethod % 2 == 0)) {
return HttpStatus.SC_NOT_FOUND;
} else {
return httpStatus;
}
}
public int getNumberOfCallsToExecuteMethod() {
return numberOfCallsToExecuteMethod;
}
public int getNumberOfCallsToExecuteMethod() {
return numberOfCallsToExecuteMethod;
}
public void setHttpStatus(int httpStatus) {
this.httpStatus = httpStatus;
}
public void setHttpStatus(int httpStatus) {
this.httpStatus = httpStatus;
}
public void setFailAlternateResponses(boolean failAlternateResponses) {
this.failAlternateResponses = failAlternateResponses;
}
public void setFailAlternateResponses(boolean failAlternateResponses) {
this.failAlternateResponses = failAlternateResponses;
}
}

View File

@ -4,31 +4,63 @@ import hudson.util.Secret;
public class MattermostNotifierStub extends MattermostNotifier {
public MattermostNotifierStub(String host, String room, String icon, String buildServerUrl,
String sendAs, boolean startNotification, boolean notifyAborted, boolean notifyFailure,
boolean notifyNotBuilt, boolean notifySuccess, boolean notifyUnstable, boolean notifyBackToNormal,
boolean notifyRepeatedFailure, boolean includeTestSummary, CommitInfoChoice commitInfoChoice,
boolean includeCustomAttachmentMessage, String customAttachmentMessage,boolean includeCustomMessage,String customMessage) {
super(host != null ? Secret.fromString(host) : null, room, icon, buildServerUrl, sendAs, startNotification, notifyAborted, notifyFailure,
notifyNotBuilt, notifySuccess, notifyUnstable, notifyBackToNormal, notifyRepeatedFailure,
includeTestSummary, commitInfoChoice, includeCustomAttachmentMessage, customAttachmentMessage, includeCustomMessage, customMessage);
}
public MattermostNotifierStub(
String host,
String room,
String icon,
String buildServerUrl,
String sendAs,
boolean startNotification,
boolean notifyAborted,
boolean notifyFailure,
boolean notifyNotBuilt,
boolean notifySuccess,
boolean notifyUnstable,
boolean notifyBackToNormal,
boolean notifyRepeatedFailure,
boolean includeTestSummary,
CommitInfoChoice commitInfoChoice,
boolean includeCustomAttachmentMessage,
String customAttachmentMessage,
boolean includeCustomMessage,
String customMessage) {
super(
host != null ? Secret.fromString(host) : null,
room,
icon,
buildServerUrl,
sendAs,
startNotification,
notifyAborted,
notifyFailure,
notifyNotBuilt,
notifySuccess,
notifyUnstable,
notifyBackToNormal,
notifyRepeatedFailure,
includeTestSummary,
commitInfoChoice,
includeCustomAttachmentMessage,
customAttachmentMessage,
includeCustomMessage,
customMessage);
}
public static class DescriptorImplStub extends MattermostNotifier.DescriptorImpl {
public static class DescriptorImplStub extends MattermostNotifier.DescriptorImpl {
private MattermostService mattermostService;
private MattermostService mattermostService;
@Override
public synchronized void load() {
}
@Override
public synchronized void load() {}
@Override
MattermostService getMattermostService(final String host, final String room, final String icon) {
return mattermostService;
}
@Override
MattermostService getMattermostService(
final String host, final String room, final String icon) {
return mattermostService;
}
public void setMattermostService(MattermostService mattermostService) {
this.mattermostService = mattermostService;
}
}
public void setMattermostService(MattermostService mattermostService) {
this.mattermostService = mattermostService;
}
}
}

View File

@ -2,17 +2,16 @@ package jenkins.plugins.mattermost;
import hudson.model.Descriptor;
import hudson.util.FormValidation;
import java.util.Arrays;
import java.util.Collection;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.Rule;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.jvnet.hudson.test.JenkinsRule;
import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized.class)
public class MattermostNotifierTest extends TestCase {
@ -21,8 +20,7 @@ public class MattermostNotifierTest extends TestCase {
private boolean response;
private FormValidation.Kind expectedResult;
@Rule
public JenkinsRule j = new JenkinsRule();
@Rule public JenkinsRule j = new JenkinsRule();
@Before
@Override
@ -31,7 +29,10 @@ public class MattermostNotifierTest extends TestCase {
descriptor = new MattermostNotifierStub.DescriptorImplStub();
}
public MattermostNotifierTest(MattermostServiceStub mattermostServiceStub, boolean response, FormValidation.Kind expectedResult) {
public MattermostNotifierTest(
MattermostServiceStub mattermostServiceStub,
boolean response,
FormValidation.Kind expectedResult) {
this.mattermostServiceStub = mattermostServiceStub;
this.response = response;
this.expectedResult = expectedResult;
@ -39,11 +40,12 @@ public class MattermostNotifierTest extends TestCase {
@Parameterized.Parameters
public static Collection businessTypeKeys() {
return Arrays.asList(new Object[][]{
{new MattermostServiceStub(), true, FormValidation.Kind.OK},
{new MattermostServiceStub(), false, FormValidation.Kind.ERROR},
{null, false, FormValidation.Kind.ERROR}
});
return Arrays.asList(
new Object[][] {
{new MattermostServiceStub(), true, FormValidation.Kind.OK},
{new MattermostServiceStub(), false, FormValidation.Kind.ERROR},
{null, false, FormValidation.Kind.ERROR}
});
}
@Test

View File

@ -2,18 +2,18 @@ package jenkins.plugins.mattermost;
public class StandardMattermostServiceStub extends StandardMattermostService {
private HttpClientStub httpClientStub;
private HttpClientStub httpClientStub;
public StandardMattermostServiceStub(String host, String roomId, String icon) {
super(host, roomId, icon);
}
public StandardMattermostServiceStub(String host, String roomId, String icon) {
super(host, roomId, icon);
}
@Override
public HttpClientStub getHttpClient() {
return httpClientStub;
}
@Override
public HttpClientStub getHttpClient() {
return httpClientStub;
}
public void setHttpClient(HttpClientStub httpClientStub) {
this.httpClientStub = httpClientStub;
}
public void setHttpClient(HttpClientStub httpClientStub) {
this.httpClientStub = httpClientStub;
}
}

View File

@ -1,122 +1,130 @@
package jenkins.plugins.mattermost;
import hudson.ProxyConfiguration;
import org.apache.http.HttpStatus;
import org.junit.Test;
import java.util.Collections;
import java.util.regex.Pattern;
import static org.junit.Assert.*;
import hudson.ProxyConfiguration;
import java.util.Collections;
import java.util.regex.Pattern;
import org.apache.http.HttpStatus;
import org.junit.Test;
public class StandardMattermostServiceTest {
/**
* Publish should generally not rethrow exceptions, or it will cause a build job to fail at end.
*/
@Test
public void publishWithBadHostShouldNotRethrowExceptions() {
StandardMattermostService service = new StandardMattermostService("foo", "#general", "");
service.setEndpoint("hostvaluethatwillcausepublishtofail");
service.publish("message");
}
/**
* Publish should generally not rethrow exceptions, or it will cause a build job to fail at end.
*/
@Test
public void publishWithBadHostShouldNotRethrowExceptions() {
StandardMattermostService service = new StandardMattermostService("foo", "#general", "");
service.setEndpoint("hostvaluethatwillcausepublishtofail");
service.publish("message");
}
/**
* Use a valid host, but an invalid team domain
*/
@Test
public void invalidHostShouldFail() {
StandardMattermostService service = new StandardMattermostService("my", "#general", "");
service.publish("message");
}
/** Use a valid host, but an invalid team domain */
@Test
public void invalidHostShouldFail() {
StandardMattermostService service = new StandardMattermostService("my", "#general", "");
service.publish("message");
}
@Test
public void publishToASingleRoomSendsASingleMessage() {
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "#room1", "");
HttpClientStub httpClientStub = new HttpClientStub();
service.setHttpClient(httpClientStub);
service.publish("message");
assertEquals(1, service.getHttpClient().getNumberOfCallsToExecuteMethod());
}
@Test
public void publishToASingleRoomSendsASingleMessage() {
StandardMattermostServiceStub service =
new StandardMattermostServiceStub("domain", "#room1", "");
HttpClientStub httpClientStub = new HttpClientStub();
service.setHttpClient(httpClientStub);
service.publish("message");
assertEquals(1, service.getHttpClient().getNumberOfCallsToExecuteMethod());
}
@Test
public void publishToMultipleRoomsSendsAMessageToEveryRoom() {
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "#room1,#room2,#room3", "");
HttpClientStub httpClientStub = new HttpClientStub();
service.setHttpClient(httpClientStub);
service.publish("message");
assertEquals(3, service.getHttpClient().getNumberOfCallsToExecuteMethod());
}
@Test
public void publishToMultipleRoomsSendsAMessageToEveryRoom() {
StandardMattermostServiceStub service =
new StandardMattermostServiceStub("domain", "#room1,#room2,#room3", "");
HttpClientStub httpClientStub = new HttpClientStub();
service.setHttpClient(httpClientStub);
service.publish("message");
assertEquals(3, service.getHttpClient().getNumberOfCallsToExecuteMethod());
}
@Test
public void successfulPublishToASingleRoomReturnsTrue() {
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "#room1", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);
assertTrue(service.publish("message"));
}
@Test
public void successfulPublishToASingleRoomReturnsTrue() {
StandardMattermostServiceStub service =
new StandardMattermostServiceStub("domain", "#room1", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);
assertTrue(service.publish("message"));
}
@Test
public void successfulPublishToMultipleRoomsReturnsTrue() {
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "#room1,#room2,#room3", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);
assertTrue(service.publish("message"));
}
@Test
public void successfulPublishToMultipleRoomsReturnsTrue() {
StandardMattermostServiceStub service =
new StandardMattermostServiceStub("domain", "#room1,#room2,#room3", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);
assertTrue(service.publish("message"));
}
@Test
public void failedPublishToASingleRoomReturnsFalse() {
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "#room1", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_NOT_FOUND);
service.setHttpClient(httpClientStub);
assertFalse(service.publish("message"));
}
@Test
public void failedPublishToASingleRoomReturnsFalse() {
StandardMattermostServiceStub service =
new StandardMattermostServiceStub("domain", "#room1", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_NOT_FOUND);
service.setHttpClient(httpClientStub);
assertFalse(service.publish("message"));
}
@Test
public void singleFailedPublishToMultipleRoomsReturnsFalse() {
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "#room1,#room2,#room3", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setFailAlternateResponses(true);
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);
assertFalse(service.publish("message"));
}
@Test
public void singleFailedPublishToMultipleRoomsReturnsFalse() {
StandardMattermostServiceStub service =
new StandardMattermostServiceStub("domain", "#room1,#room2,#room3", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setFailAlternateResponses(true);
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);
assertFalse(service.publish("message"));
}
@Test
public void publishToEmptyRoomReturnsTrue() {
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);
assertTrue(service.publish("message"));
}
@Test
public void publishToEmptyRoomReturnsTrue() {
StandardMattermostServiceStub service = new StandardMattermostServiceStub("domain", "", "");
HttpClientStub httpClientStub = new HttpClientStub();
httpClientStub.setHttpStatus(HttpStatus.SC_OK);
service.setHttpClient(httpClientStub);
assertTrue(service.publish("message"));
}
@Test
public void isProxyRequiredEmtyNoProxyHostsReturnsTrue() {
StandardMattermostService service = new StandardMattermostService("http://mymattermost.endpoint.com","roomid","icon");
assertTrue(service.isProxyRequired(Collections.<Pattern>emptyList()));
}
@Test
public void isProxyRequiredEmtyNoProxyHostsReturnsTrue() {
StandardMattermostService service =
new StandardMattermostService("http://mymattermost.endpoint.com", "roomid", "icon");
assertTrue(service.isProxyRequired(Collections.<Pattern>emptyList()));
}
@Test
public void isProxyRequiredNoProxyHostsDoesNotMatchReturnsTrue() {
StandardMattermostService service = new StandardMattermostService("http://mymattermost.endpoint.com","roomid","icon");
assertTrue(service.isProxyRequired(ProxyConfiguration.getNoProxyHostPatterns("*.internal.com")));
}
@Test
public void isProxyRequiredNoProxyHostsMatchReturnsFalse() {
StandardMattermostService service = new StandardMattermostService("http://mymattermost.endpoint.com","roomid","icon");
assertFalse(service.isProxyRequired(ProxyConfiguration.getNoProxyHostPatterns("*.endpoint.com")));
}
@Test
public void isProxyRequiredInvalidEndPointReturnsTrue() {
StandardMattermostService service = new StandardMattermostService("htt://mymattermost.endpoint.com","roomid","icon");
assertTrue(service.isProxyRequired(ProxyConfiguration.getNoProxyHostPatterns("*.internal.com")));
}
@Test
public void isProxyRequiredNoProxyHostsDoesNotMatchReturnsTrue() {
StandardMattermostService service =
new StandardMattermostService("http://mymattermost.endpoint.com", "roomid", "icon");
assertTrue(
service.isProxyRequired(ProxyConfiguration.getNoProxyHostPatterns("*.internal.com")));
}
@Test
public void isProxyRequiredNoProxyHostsMatchReturnsFalse() {
StandardMattermostService service =
new StandardMattermostService("http://mymattermost.endpoint.com", "roomid", "icon");
assertFalse(
service.isProxyRequired(ProxyConfiguration.getNoProxyHostPatterns("*.endpoint.com")));
}
@Test
public void isProxyRequiredInvalidEndPointReturnsTrue() {
StandardMattermostService service =
new StandardMattermostService("htt://mymattermost.endpoint.com", "roomid", "icon");
assertTrue(
service.isProxyRequired(ProxyConfiguration.getNoProxyHostPatterns("*.internal.com")));
}
}

View File

@ -1,6 +1,5 @@
package jenkins.plugins.mattermost.workflow;
import hudson.model.Result;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
@ -11,39 +10,49 @@ import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
public class MattermostSendStepIntegrationTest {
@Rule
public JenkinsRule jenkinsRule = new JenkinsRule();
@Rule public JenkinsRule jenkinsRule = new JenkinsRule();
@Test
public void configRoundTrip() throws Exception {
MattermostSendStep step1 = new MattermostSendStep("message");
step1.setColor("good");
step1.setChannel("#channel");
step1.setIcon("icon");
step1.setEndpoint("teamDomain");
step1.setFailOnError(true);
@Test
public void configRoundTrip() throws Exception {
MattermostSendStep step1 = new MattermostSendStep("message");
step1.setColor("good");
step1.setChannel("#channel");
step1.setIcon("icon");
step1.setEndpoint("teamDomain");
step1.setFailOnError(true);
MattermostSendStep step2 = new StepConfigTester(jenkinsRule).configRoundTrip(step1);
jenkinsRule.assertEqualDataBoundBeans(step1, step2);
}
MattermostSendStep step2 = new StepConfigTester(jenkinsRule).configRoundTrip(step1);
jenkinsRule.assertEqualDataBoundBeans(step1, step2);
}
@Test
public void test_global_config_override() throws Exception {
WorkflowJob job = jenkinsRule.jenkins.createProject(WorkflowJob.class, "workflow");
//just define message
job.setDefinition(new CpsFlowDefinition("mattermostSend(message: 'message', endpoint: 'endpoint', icon: 'icon', channel: '#channel', color: 'good');", true));
WorkflowRun run = jenkinsRule.assertBuildStatusSuccess(job.scheduleBuild2(0).get());
//everything should come from step configuration
jenkinsRule.assertLogContains(String.format("Mattermost Send Pipeline step configured values from global config - connector: %s, icon: %s, channel: %s, color: %s", false, false, false, false), run);
}
@Test
public void test_global_config_override() throws Exception {
WorkflowJob job = jenkinsRule.jenkins.createProject(WorkflowJob.class, "workflow");
// just define message
job.setDefinition(
new CpsFlowDefinition(
"mattermostSend(message: 'message', endpoint: 'endpoint', icon: 'icon', channel: '#channel', color: 'good');",
true));
WorkflowRun run = jenkinsRule.assertBuildStatusSuccess(job.scheduleBuild2(0).get());
// everything should come from step configuration
jenkinsRule.assertLogContains(
String.format(
"Mattermost Send Pipeline step configured values from global config - connector: %s, icon: %s, channel: %s, color: %s",
false, false, false, false),
run);
}
@Test
public void test_fail_on_error() throws Exception {
WorkflowJob job = jenkinsRule.jenkins.createProject(WorkflowJob.class, "workflow");
//just define message
job.setDefinition(new CpsFlowDefinition("mattermostSend(message: 'message', endpoint: 'endpoint', icon: 'icon', channel: '#channel', color: 'good', failOnError: true);", true));
WorkflowRun run = jenkinsRule.assertBuildStatus(Result.FAILURE, job.scheduleBuild2(0).get());
//everything should come from step configuration
jenkinsRule.assertLogContains("Mattermost notification failed. See Jenkins logs for details.", run);
}
@Test
public void test_fail_on_error() throws Exception {
WorkflowJob job = jenkinsRule.jenkins.createProject(WorkflowJob.class, "workflow");
// just define message
job.setDefinition(
new CpsFlowDefinition(
"mattermostSend(message: 'message', endpoint: 'endpoint', icon: 'icon', channel: '#channel', color: 'good', failOnError: true);",
true));
WorkflowRun run = jenkinsRule.assertBuildStatus(Result.FAILURE, job.scheduleBuild2(0).get());
// everything should come from step configuration
jenkinsRule.assertLogContains(
"Mattermost notification failed. See Jenkins logs for details.", run);
}
}

View File

@ -1,7 +1,14 @@
package jenkins.plugins.mattermost.workflow;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.*;
import static org.powermock.api.mockito.PowerMockito.spy;
import hudson.model.TaskListener;
import hudson.util.Secret;
import java.io.PrintStream;
import java.io.PrintWriter;
import jenkins.model.Jenkins;
import jenkins.plugins.mattermost.MattermostNotifier;
import jenkins.plugins.mattermost.MattermostService;
@ -13,168 +20,162 @@ import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.io.PrintStream;
import java.io.PrintWriter;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.*;
import static org.powermock.api.mockito.PowerMockito.spy;
/**
* Traditional Unit tests, allows testing null Jenkins,getInstance()
*/
/** Traditional Unit tests, allows testing null Jenkins,getInstance() */
@RunWith(PowerMockRunner.class)
@PrepareForTest({Jenkins.class, ConfidentialStore.class, MattermostSendStep.class})
@PowerMockIgnore({"javax.crypto.*" }) // https://github.com/powermock/powermock/issues/294
@PowerMockIgnore({"javax.crypto.*"}) // https://github.com/powermock/powermock/issues/294
public class MattermostSendStepTest {
@Mock
TaskListener taskListenerMock;
@Mock
PrintStream printStreamMock;
@Mock
PrintWriter printWriterMock;
@Mock
StepContext stepContextMock;
@Mock
MattermostService mattermostServiceMock;
@Mock
Jenkins jenkins;
@Mock
MattermostNotifier.DescriptorImpl mattermostDescMock;
@Mock TaskListener taskListenerMock;
@Mock PrintStream printStreamMock;
@Mock PrintWriter printWriterMock;
@Mock StepContext stepContextMock;
@Mock MattermostService mattermostServiceMock;
@Mock Jenkins jenkins;
@Mock MattermostNotifier.DescriptorImpl mattermostDescMock;
@Before
public void setUp() {
PowerMockito.mockStatic(Jenkins.class);
when(jenkins.getDescriptorByType(MattermostNotifier.DescriptorImpl.class)).thenReturn(mattermostDescMock);
}
@Before
public void setUp() {
PowerMockito.mockStatic(Jenkins.class);
when(jenkins.getDescriptorByType(MattermostNotifier.DescriptorImpl.class))
.thenReturn(mattermostDescMock);
}
@Test
public void testStepOverrides() throws Exception {
MattermostSendStep.SlackSendStepExecution stepExecution = spy(new MattermostSendStep.SlackSendStepExecution());
MattermostSendStep mattermostSendStep = new MattermostSendStep("message");
mattermostSendStep.setIcon("icon");
mattermostSendStep.setEndpoint("endpoint");
mattermostSendStep.setChannel("channel");
mattermostSendStep.setColor("good");
stepExecution.step = mattermostSendStep;
@Test
public void testStepOverrides() throws Exception {
MattermostSendStep.SlackSendStepExecution stepExecution =
spy(new MattermostSendStep.SlackSendStepExecution());
MattermostSendStep mattermostSendStep = new MattermostSendStep("message");
mattermostSendStep.setIcon("icon");
mattermostSendStep.setEndpoint("endpoint");
mattermostSendStep.setChannel("channel");
mattermostSendStep.setColor("good");
stepExecution.step = mattermostSendStep;
when(Jenkins.getInstance()).thenReturn(jenkins);
when(Jenkins.getInstance()).thenReturn(jenkins);
stepExecution.listener = taskListenerMock;
stepExecution.listener = taskListenerMock;
when(mattermostDescMock.getIcon()).thenReturn("differentIcon");
when(mattermostDescMock.getIcon()).thenReturn("differentIcon");
when(taskListenerMock.getLogger()).thenReturn(printStreamMock);
doNothing().when(printStreamMock).println();
when(taskListenerMock.getLogger()).thenReturn(printStreamMock);
doNothing().when(printStreamMock).println();
when(stepExecution.getMattermostService(anyString(), anyString(), anyString()))
.thenReturn(mattermostServiceMock);
when(mattermostServiceMock.publish(anyString(), anyString())).thenReturn(true);
when(stepExecution.getMattermostService(anyString(), anyString(), anyString())).thenReturn(mattermostServiceMock);
when(mattermostServiceMock.publish(anyString(), anyString())).thenReturn(true);
stepExecution.run();
verify(stepExecution, times(1)).getMattermostService("endpoint", "channel", "icon");
verify(mattermostServiceMock, times(1)).publish("message", "", "good");
assertFalse(stepExecution.step.isFailOnError());
}
stepExecution.run();
verify(stepExecution, times(1)).getMattermostService("endpoint", "channel", "icon");
verify(mattermostServiceMock, times(1)).publish("message", "", "good");
assertFalse(stepExecution.step.isFailOnError());
}
@Test
public void testValuesForGlobalConfig() throws Exception {
@Test
public void testValuesForGlobalConfig() throws Exception {
MattermostSendStep.SlackSendStepExecution stepExecution =
spy(new MattermostSendStep.SlackSendStepExecution());
stepExecution.step = new MattermostSendStep("message");
MattermostSendStep.SlackSendStepExecution stepExecution = spy(new MattermostSendStep.SlackSendStepExecution());
stepExecution.step = new MattermostSendStep("message");
when(Jenkins.getInstance()).thenReturn(jenkins);
when(Jenkins.getInstance()).thenReturn(jenkins);
stepExecution.listener = taskListenerMock;
stepExecution.listener = taskListenerMock;
PowerMockito.mockStatic(ConfidentialStore.class);
ConfidentialStore csMock = mock(ConfidentialStore.class);
when(ConfidentialStore.get()).thenReturn(csMock);
when(csMock.randomBytes(Matchers.anyInt()))
.thenAnswer(it -> new byte[(Integer) (it.getArguments()[0])]);
PowerMockito.mockStatic(ConfidentialStore.class);
ConfidentialStore csMock = mock(ConfidentialStore.class);
when(ConfidentialStore.get()).thenReturn(csMock);
when(csMock.randomBytes(Matchers.anyInt())).thenAnswer( it -> new byte[ (Integer)(it.getArguments()[0])] );
Secret encryptedEndpoint = Secret.fromString("globalEndpoint");
when(mattermostDescMock.getEndpoint()).thenReturn(encryptedEndpoint);
when(mattermostDescMock.getIcon()).thenReturn("globalIcon");
when(mattermostDescMock.getRoom()).thenReturn("globalChannel");
Secret encryptedEndpoint = Secret.fromString("globalEndpoint");
when(mattermostDescMock.getEndpoint()).thenReturn(encryptedEndpoint);
when(mattermostDescMock.getIcon()).thenReturn("globalIcon");
when(mattermostDescMock.getRoom()).thenReturn("globalChannel");
when(taskListenerMock.getLogger()).thenReturn(printStreamMock);
doNothing().when(printStreamMock).println();
when(taskListenerMock.getLogger()).thenReturn(printStreamMock);
doNothing().when(printStreamMock).println();
when(stepExecution.getMattermostService(anyString(), anyString(), anyString()))
.thenReturn(mattermostServiceMock);
when(stepExecution.getMattermostService(anyString(), anyString(), anyString())).thenReturn(mattermostServiceMock);
stepExecution.run();
verify(stepExecution, times(1))
.getMattermostService("globalEndpoint", "globalChannel", "globalIcon");
verify(mattermostServiceMock, times(1)).publish("message", "", "");
assertNull(stepExecution.step.getEndpoint());
assertNull(stepExecution.step.getIcon());
assertNull(stepExecution.step.getChannel());
assertNull(stepExecution.step.getColor());
assertNull(stepExecution.step.getText());
}
stepExecution.run();
verify(stepExecution, times(1)).getMattermostService("globalEndpoint", "globalChannel", "globalIcon");
verify(mattermostServiceMock, times(1)).publish("message", "", "");
assertNull(stepExecution.step.getEndpoint());
assertNull(stepExecution.step.getIcon());
assertNull(stepExecution.step.getChannel());
assertNull(stepExecution.step.getColor());
assertNull(stepExecution.step.getText());
}
@Test
public void testNonNullEmptyColor() throws Exception {
@Test
public void testNonNullEmptyColor() throws Exception {
MattermostSendStep.SlackSendStepExecution stepExecution =
spy(new MattermostSendStep.SlackSendStepExecution());
MattermostSendStep mattermostSendStep = new MattermostSendStep("message");
mattermostSendStep.setColor("");
stepExecution.step = mattermostSendStep;
MattermostSendStep.SlackSendStepExecution stepExecution = spy(new MattermostSendStep.SlackSendStepExecution());
MattermostSendStep mattermostSendStep = new MattermostSendStep("message");
mattermostSendStep.setColor("");
stepExecution.step = mattermostSendStep;
when(Jenkins.getInstance()).thenReturn(jenkins);
when(Jenkins.getInstance()).thenReturn(jenkins);
stepExecution.listener = taskListenerMock;
stepExecution.listener = taskListenerMock;
when(taskListenerMock.getLogger()).thenReturn(printStreamMock);
doNothing().when(printStreamMock).println();
when(taskListenerMock.getLogger()).thenReturn(printStreamMock);
doNothing().when(printStreamMock).println();
when(stepExecution.getMattermostService(anyString(), anyString(), anyString()))
.thenReturn(mattermostServiceMock);
when(stepExecution.getMattermostService(anyString(), anyString(), anyString())).thenReturn(mattermostServiceMock);
stepExecution.run();
verify(mattermostServiceMock, times(1)).publish("message", "", "");
assertNull(stepExecution.step.getColor());
}
stepExecution.run();
verify(mattermostServiceMock, times(1)).publish("message", "", "");
assertNull(stepExecution.step.getColor());
}
@Test
public void testNonNullPretext() throws Exception {
@Test
public void testNonNullPretext() throws Exception {
MattermostSendStep.SlackSendStepExecution stepExecution =
spy(new MattermostSendStep.SlackSendStepExecution());
MattermostSendStep mattermostSendStep = new MattermostSendStep("message");
mattermostSendStep.setText("@foo @bar");
stepExecution.step = mattermostSendStep;
MattermostSendStep.SlackSendStepExecution stepExecution = spy(new MattermostSendStep.SlackSendStepExecution());
MattermostSendStep mattermostSendStep = new MattermostSendStep("message");
mattermostSendStep.setText("@foo @bar");
stepExecution.step = mattermostSendStep;
when(Jenkins.getInstance()).thenReturn(jenkins);
when(Jenkins.getInstance()).thenReturn(jenkins);
stepExecution.listener = taskListenerMock;
stepExecution.listener = taskListenerMock;
when(taskListenerMock.getLogger()).thenReturn(printStreamMock);
doNothing().when(printStreamMock).println();
when(taskListenerMock.getLogger()).thenReturn(printStreamMock);
doNothing().when(printStreamMock).println();
when(stepExecution.getMattermostService(anyString(), anyString(), anyString()))
.thenReturn(mattermostServiceMock);
when(stepExecution.getMattermostService(anyString(), anyString(), anyString())).thenReturn(mattermostServiceMock);
stepExecution.run();
verify(mattermostServiceMock, times(1)).publish("message", "@foo @bar", "");
}
stepExecution.run();
verify(mattermostServiceMock, times(1)).publish("message", "@foo @bar", "");
}
@Test
public void testNullJenkinsInstance() throws Exception {
@Test
public void testNullJenkinsInstance() throws Exception {
MattermostSendStep.SlackSendStepExecution stepExecution =
spy(new MattermostSendStep.SlackSendStepExecution());
stepExecution.step = new MattermostSendStep("message");
MattermostSendStep.SlackSendStepExecution stepExecution = spy(new MattermostSendStep.SlackSendStepExecution());
stepExecution.step = new MattermostSendStep("message");
when(Jenkins.getInstance()).thenThrow(NullPointerException.class);
when(Jenkins.getInstance()).thenThrow(NullPointerException.class);
stepExecution.listener = taskListenerMock;
stepExecution.listener = taskListenerMock;
when(taskListenerMock.error(anyString())).thenReturn(printWriterMock);
doNothing().when(printStreamMock).println();
when(taskListenerMock.error(anyString())).thenReturn(printWriterMock);
doNothing().when(printStreamMock).println();
stepExecution.run();
verify(taskListenerMock, times(1)).error(anyString(), any(Exception.class));
}
stepExecution.run();
verify(taskListenerMock, times(1)).error(anyString(), any(Exception.class));
}
}