diff --git a/pom.xml b/pom.xml index 76008ab..41a1378 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ http://wiki.jenkins-ci.org/display/JENKINS/Job+Import+Plugin - 1.580.3 + 1.609.1 6 false @@ -103,6 +103,18 @@ credentials 1.24 + + org.jenkins-ci.plugins + cloudbees-folder + 5.12 + + + + com.github.tomakehurst + wiremock + 1.58 + test + diff --git a/src/main/java/org/jenkins/ci/plugins/jobimport/CredentialsUtils.java b/src/main/java/org/jenkins/ci/plugins/jobimport/CredentialsUtils.java new file mode 100644 index 0000000..4cb11bd --- /dev/null +++ b/src/main/java/org/jenkins/ci/plugins/jobimport/CredentialsUtils.java @@ -0,0 +1,59 @@ +package org.jenkins.ci.plugins.jobimport; + +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.domains.DomainRequirement; +import com.google.common.base.Strings; +import hudson.model.Item; +import hudson.security.ACL; + +import java.util.Collections; +import java.util.List; + +import static com.google.inject.internal.guava.base.$Preconditions.checkNotNull; + +/** + * Created by evildethow on 28/06/2016. + */ +final class CredentialsUtils { + + private CredentialsUtils() { + throw new UnsupportedOperationException("Cannot instantiate utility class"); + } + + static NullSafeCredentials getCredentials(String credentialId) { + if (!Strings.isNullOrEmpty(credentialId)) { + StandardUsernamePasswordCredentials cred = CredentialsMatchers.firstOrNull(allCredentials(), CredentialsMatchers.withId(credentialId)); + if (cred != null) { + return new NullSafeCredentials(cred.getUsername(), cred.getPassword().getPlainText()); + } + } + return new NullSafeCredentials(); + } + + static List allCredentials() { + return CredentialsProvider.lookupCredentials( + StandardUsernamePasswordCredentials.class, + (Item) null, + ACL.SYSTEM, + Collections.emptyList() + ); + } + + static final class NullSafeCredentials { + + final String username; + final String password; + + NullSafeCredentials(String username, String password) { + this.username = checkNotNull(username); + this.password = checkNotNull(password); + } + + NullSafeCredentials() { + this.username = ""; + this.password = ""; + } + } +} diff --git a/src/main/java/org/jenkins/ci/plugins/jobimport/JobImportAction.java b/src/main/java/org/jenkins/ci/plugins/jobimport/JobImportAction.java index ed9ac16..f933920 100644 --- a/src/main/java/org/jenkins/ci/plugins/jobimport/JobImportAction.java +++ b/src/main/java/org/jenkins/ci/plugins/jobimport/JobImportAction.java @@ -24,39 +24,18 @@ package org.jenkins.ci.plugins.jobimport; -import com.cloudbees.plugins.credentials.CredentialsMatchers; -import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.common.StandardUsernameListBoxModel; -import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; -import com.cloudbees.plugins.credentials.domains.DomainRequirement; -import com.google.common.base.Strings; import hudson.Extension; import hudson.model.Describable; import hudson.model.Descriptor; -import hudson.model.Item; import hudson.model.RootAction; import hudson.model.TopLevelItem; -import hudson.model.AbstractProject; -import hudson.security.ACL; import hudson.util.FormValidation; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.xml.parsers.DocumentBuilderFactory; - import hudson.util.ListBoxModel; import jenkins.model.Jenkins; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; +import org.jenkins.ci.plugins.jobimport.CredentialsUtils.NullSafeCredentials; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -64,6 +43,21 @@ import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import javax.servlet.ServletException; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.jenkins.ci.plugins.jobimport.CredentialsUtils.allCredentials; +import static org.jenkins.ci.plugins.jobimport.RemoteJobUtils.getRemoteJob; + /** * @author Jesse Farinacci * @since 1.0 @@ -73,6 +67,11 @@ public final class JobImportAction implements RootAction, Describable getRemoteJobs() { return remoteJobs; } - private RemoteJob getRemoteJobs(final String jobUrl) { - if (StringUtils.isNotEmpty(jobUrl)) { - for (final RemoteJob remoteJob : remoteJobs) { - if (jobUrl.equals(remoteJob.getUrl())) { - return remoteJob; - } - } - } - - return null; - } - public SortedMap getRemoteJobsImportStatus() { return remoteJobsImportStatus; } @@ -258,7 +239,7 @@ public String getRemoteUrl() { } public String getUrlName() { - return "/job-import"; + return "/" + URL_NAME; } public boolean isRemoteJobsAvailable() { @@ -275,23 +256,11 @@ public void setRemoteUrl(final String remoteUrl) { public String getCredentialId() { return credentialId; } - private static List allCredentials() { - return CredentialsProvider.lookupCredentials( - StandardUsernamePasswordCredentials.class, - (Item) null, - ACL.SYSTEM, - Collections.emptyList() - ); - } + @Override public Descriptor getDescriptor() { - // TODO switch to Jenkins.getActiveInstance() once 1.590+ is the baseline - Jenkins jenkins = Jenkins.getInstance(); - if (jenkins == null) { - throw new IllegalStateException("Jenkins has not been started, or was already shut down"); - } - return jenkins.getDescriptorOrDie(getClass()); + return Jenkins.getActiveInstance().getDescriptorOrDie(getClass()); } @Extension diff --git a/src/main/java/org/jenkins/ci/plugins/jobimport/RemoteJob.java b/src/main/java/org/jenkins/ci/plugins/jobimport/RemoteJob.java index ff38a2e..edb500f 100644 --- a/src/main/java/org/jenkins/ci/plugins/jobimport/RemoteJob.java +++ b/src/main/java/org/jenkins/ci/plugins/jobimport/RemoteJob.java @@ -24,61 +24,63 @@ package org.jenkins.ci.plugins.jobimport; -import org.apache.commons.lang.StringEscapeUtils; -import org.apache.commons.lang.StringUtils; +import java.util.SortedSet; +import java.util.TreeSet; + +import static org.jenkins.ci.plugins.jobimport.RemoteJobUtils.cleanRemoteString; +import static org.jenkins.ci.plugins.jobimport.RemoteJobUtils.fullName; /** * @author Jesse Farinacci * @since 1.0 */ public final class RemoteJob implements Comparable { - private String name; - private String url; - private String description; - - public RemoteJob() { - this((String) null, (String) null, (String) null); - } - - public RemoteJob(final String name) { - this(name, (String) null, (String) null); - } - - public RemoteJob(final String name, final String url) { - this(name, url, (String) null); - } + private final String name; + private final String url; + private final String description; + private final RemoteJob parent; + private final SortedSet children = new TreeSet(); - public RemoteJob(final String name, final String url, final String description) { - super(); + public RemoteJob(final String name, final String url, final String description, RemoteJob parent) { this.name = name; this.url = url; - this.description = cleanRemoteString(description); + this.description = cleanRemoteString(description != null ? description : ""); + this.parent = parent; } public String getName() { return name; } - public void setName(final String name) { - this.name = name; - } - public String getUrl() { return url; } - public void setUrl(final String url) { - this.url = url; - } - public String getDescription() { return description; } - public void setDescription(final String description) { - this.description = cleanRemoteString(description); + public RemoteJob getParent() { + return parent; + } + + public SortedSet getChildren() { + return children; + } + + boolean hasChildren() { + return !this.children.isEmpty(); + } + + boolean hasParent() { + return this.parent != null; + } + + public String getFullName() { + return fullName(this); } + @Override public int compareTo(final RemoteJob other) { if (this == other) { return 0; @@ -89,15 +91,8 @@ public int compareTo(final RemoteJob other) { @Override public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - - if (!(obj instanceof RemoteJob)) { - return false; - } + return this == obj || obj instanceof RemoteJob && name.equals(((RemoteJob) obj).getName()); - return name.equals(((RemoteJob) obj).getName()); } @Override @@ -107,13 +102,6 @@ public int hashCode() { @Override public String toString() { - return new StringBuilder().append("RemoteJob: ").append(name).append(", ").append(url).append(", ") - .append(description).toString(); - } - - protected static final int MAX_STRLEN = 4096; - - protected static final String cleanRemoteString(final String string) { - return StringUtils.substring(StringEscapeUtils.escapeHtml(string), 0, MAX_STRLEN); + return "RemoteJob: " + name + ", " + url + ", " + description; } } diff --git a/src/main/java/org/jenkins/ci/plugins/jobimport/RemoteJobUtils.java b/src/main/java/org/jenkins/ci/plugins/jobimport/RemoteJobUtils.java new file mode 100644 index 0000000..5cbcfda --- /dev/null +++ b/src/main/java/org/jenkins/ci/plugins/jobimport/RemoteJobUtils.java @@ -0,0 +1,61 @@ +package org.jenkins.ci.plugins.jobimport; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.SortedSet; + +/** + * Created by evildethow on 28/06/2016. + */ +final class RemoteJobUtils { + + private RemoteJobUtils() { + throw new UnsupportedOperationException("Cannot instantiate utility class"); + } + + static String fullName(RemoteJob remoteJob) { + if (remoteJob == null) { + return ""; + } + + if (!remoteJob.hasParent()) { + return remoteJob.getName(); + } + + return StringUtils.substringBeforeLast(fullName(remoteJob, ""), "jobs/"); + } + + private static String fullName(RemoteJob remoteJob, String name) { + name = remoteJob.getName() + "/jobs/" + name; + return remoteJob.hasParent() ? fullName(remoteJob.getParent(), name) : name; + } + + private static final int MAX_STR_LEN = 4096; + + static String cleanRemoteString(final String string) { + return StringUtils.substring(StringEscapeUtils.escapeHtml(string), 0, MAX_STR_LEN); + } + + static RemoteJob getRemoteJob(SortedSet remoteJobs, String jobUrl) { + List matches = new ArrayList(); + + findRemoteJob(remoteJobs, jobUrl, matches); + + return matches.isEmpty() ? null : matches.get(0); + } + + private static void findRemoteJob(SortedSet remoteJobs, String jobUrl, List matches) { + if (StringUtils.isNotEmpty(jobUrl) && matches.isEmpty()) { + for (final RemoteJob remoteJob : remoteJobs) { + if (jobUrl.trim().equals(remoteJob.getUrl().trim())) { + matches.add(remoteJob); + } else if (remoteJob.hasChildren()) { + findRemoteJob(remoteJob.getChildren(), jobUrl, matches); + } + } + } + } +} diff --git a/src/test/java/org/jenkins/ci/plugins/jobimport/JobImportActionTest.java b/src/test/java/org/jenkins/ci/plugins/jobimport/JobImportActionTest.java new file mode 100644 index 0000000..2a255b8 --- /dev/null +++ b/src/test/java/org/jenkins/ci/plugins/jobimport/JobImportActionTest.java @@ -0,0 +1,42 @@ +package org.jenkins.ci.plugins.jobimport; + +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; + +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; + +/** + * Created by evildethow on 29/06/2016. + */ +public class JobImportActionTest { + + @Rule + public JenkinsRule jenkinsRule = new JenkinsRule(); + + @Rule + public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort()); + + private JobImportClient client; + private RemoteJenkins remoteJenkins; + + @Before + public void setUp() throws Exception { + client = new JobImportClient(jenkinsRule.createWebClient()); + remoteJenkins = new RemoteJenkins(wireMockRule.port()); + } + + @Test + public void doImport() throws Exception { + client.doQuerySubmit(remoteJenkins.getUrl()); + + remoteJenkins.verifyQueried(); + + client.selectJobs(); + client.doImportSubmit(); + + remoteJenkins.verifyImported(); + } +} diff --git a/src/test/java/org/jenkins/ci/plugins/jobimport/JobImportClient.java b/src/test/java/org/jenkins/ci/plugins/jobimport/JobImportClient.java new file mode 100644 index 0000000..e9838ad --- /dev/null +++ b/src/test/java/org/jenkins/ci/plugins/jobimport/JobImportClient.java @@ -0,0 +1,56 @@ +package org.jenkins.ci.plugins.jobimport; + +import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; +import com.gargoylesoftware.htmlunit.html.*; +import org.jvnet.hudson.test.JenkinsRule; + +import static org.jenkins.ci.plugins.jobimport.JobImportAction.JOB_URL_PARAM; +import static org.jenkins.ci.plugins.jobimport.JobImportAction.REMOTE_URL_PARAM; +import static org.jenkins.ci.plugins.jobimport.JobImportAction.URL_NAME; + +/** + * Created by evildethow on 30/06/2016. + */ +public final class JobImportClient { + + private static final int IMPORT_SUBMIT_RETRY = 5; + private static final long IMPORT_SUBMIT_RETRY_WAIT_TIME = 1000L; + + private HtmlPage currentPage; + + public JobImportClient(JenkinsRule.WebClient webClient) throws Exception { + this.currentPage = webClient.goTo(URL_NAME); + } + + public void doQuerySubmit(String remoteUrl) throws Exception { + HtmlInput input = (HtmlInput) currentPage.getElementsByName(REMOTE_URL_PARAM).get(0); + input.setValueAttribute(remoteUrl); + HtmlForm form = currentPage.getFormByName("query"); + currentPage = form.getInputByValue("Query!").click(); + } + + public void selectJobs() { + for (DomElement checkBox : currentPage.getElementsByName(JOB_URL_PARAM)) { + ((HtmlCheckBoxInput) checkBox).setChecked(true); + } + } + + public void doImportSubmit() throws Exception { + doImportSubmitWithRetry(IMPORT_SUBMIT_RETRY); + } + + private void doImportSubmitWithRetry(int retry) throws Exception { + try { + HtmlForm form = currentPage.getFormByName("import"); + currentPage = form.getInputByValue("Import!").click(); + } catch (FailingHttpStatusCodeException e) { + if (retry > 0) { + Thread.sleep(IMPORT_SUBMIT_RETRY_WAIT_TIME); + retry--; + doImportSubmitWithRetry(retry); + } else { + throw e; + } + } + } +} diff --git a/src/test/java/org/jenkins/ci/plugins/jobimport/RemoteJenkins.java b/src/test/java/org/jenkins/ci/plugins/jobimport/RemoteJenkins.java new file mode 100644 index 0000000..d7628f9 --- /dev/null +++ b/src/test/java/org/jenkins/ci/plugins/jobimport/RemoteJenkins.java @@ -0,0 +1,166 @@ +package org.jenkins.ci.plugins.jobimport; + +import org.apache.commons.io.IOUtils; + +import java.io.IOException; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static java.io.File.separator; +import static org.jenkins.ci.plugins.jobimport.JobImportAction.XML_API_QUERY; + +/** + * Created by evildethow on 30/06/2016. + */ +public final class RemoteJenkins { + + private static final String BASE_URL = "http://localhost"; + + private static final String TOP_LVL_RSP_XML = "xml-api-response.xml"; + private static final String SECOND_LVL_RSP_XML = "folder" + separator + "xml-api-response.xml"; + private static final String THIRD_LVL_RSP_XML = "folder" + separator + "jobs" + separator + "aFolder" + separator + "xml-api-response.xml"; + + private static final String TOP_LVL_QUERY = XML_API_QUERY; + private static final String SECOND_LVL_FOLDER_QUERY = "/job/folder/" + XML_API_QUERY; + private static final String SECOND_LVL_JOB_QUERY = "/job/job/" + XML_API_QUERY; + private static final String THIRD_LVL_A_FOLDER_QUERY = "/job/folder/job/aFolder/" + XML_API_QUERY; + private static final String THIRD_LVL_A_FREESTYLE_JOB_IN_FOLDER_QUERY = "/job/folder/job/aFreestyleJobInFolder/" + XML_API_QUERY; + private static final String THIRD_LVL_A_MAVEN_JOB_IN_FOLDER_QUERY = "/job/folder/job/aMavenJobInFolder/" + XML_API_QUERY; + private static final String FOURTH_LVL_B_FREESTYLE_JOB_IN_A_FOLDER_QUERY = "/job/folder/job/aFolder/job/bFreestyleJobInFolder/" + XML_API_QUERY; + private static final String FOURTH_LVL_B_MAVEN_JOB_IN_A_FOLDER_QUERY = "/job/folder/job/aFolder/job/bMavenJobInFolder/" + XML_API_QUERY; + + private static final String EMPTY_FREESTYLE_JOB_BODY = ""; + private static final String EMPTY_MAVEN_JOB_BODY = ""; + + private static final String FOLDER_CONFIG_QUERY = "/job/folder//config.xml"; + private static final String JOB_CONFIG_QUERY = "/job/job//config.xml"; + private static final String A_FOLDER_CONFIG_QUERY = "/job/folder/job/aFolder//config.xml"; + private static final String A_FREESTYLE_JOB_IN_FOLDER_CONFIG_QUERY = "/job/folder/job/aFreestyleJobInFolder//config.xml"; + private static final String A_MAVEN_JOB_IN_FOLDER_CONFIG_QUERY = "/job/folder/job/aMavenJobInFolder//config.xml"; + private static final String B_FREESTYLE_JOB_IN_FOLDER_CONFIG_QUERY = "/job/folder/job/aFolder/job/bFreestyleJobInFolder//config.xml"; + private static final String B_MAVEN_JOB_IN_FOLDER_CONFIG_QUERY = "/job/folder/job/aFolder/job/bMavenJobInFolder//config.xml"; + + private static final String FOLDER_CONFIG = "folder" + separator + "config.xml"; + private static final String JOB_CONFIG = "job" + separator + "config.xml"; + private static final String A_FOLDER_CONFIG = "folder" + separator + "jobs" + separator + "aFolder" + separator + "config.xml"; + private static final String A_FREESTYLE_JOB_IN_FOLDER_CONFIG = "folder" + separator + "jobs" + separator + "aFreestyleJobInFolder" + separator + "config.xml"; + private static final String A_MAVEN_JOB_IN_FOLDER_CONFIG = "folder" + separator + "jobs" + separator + "aMavenJobInFolder" + separator + "config.xml"; + private static final String B_FREESTYLE_JOB_IN_FOLDER_CONFIG = "folder" + separator + "jobs" + separator + "aFolder" + separator + "jobs" + separator + "bFreestyleJobInFolder" + separator + "config.xml"; + private static final String B_MAVEN_JOB_IN_FOLDER_CONFIG = "folder" + separator + "jobs" + separator + "aFolder" + separator + "jobs" + separator + "bMavenJobInFolder" + separator + "config.xml"; + + private final String url; + + public RemoteJenkins(int port) { + this.url = BASE_URL + ":" + port; + + stubQueryResponses(); + stubImportResponses(); + } + + private void stubQueryResponses() { + stubTopLevelResponse(); + stubSecondLevelResponse(); + stubThirdLevelResponse(); + stubFourthLevelResponse(); + } + + private void stubImportResponses() { + stubTopLevelConfigResponse(); + stubSecondLevelConfigResponse(); + stubThirdLevelConfigResponse(); + } + + private void stubTopLevelResponse() { + stubGetRequest(TOP_LVL_QUERY, getResponse(TOP_LVL_RSP_XML)); + } + + private void stubSecondLevelResponse() { + stubGetRequest(SECOND_LVL_FOLDER_QUERY, getResponse(SECOND_LVL_RSP_XML)); + stubGetRequest(SECOND_LVL_JOB_QUERY, EMPTY_FREESTYLE_JOB_BODY); + } + + private void stubThirdLevelResponse() { + stubGetRequest(THIRD_LVL_A_FOLDER_QUERY, getResponse(THIRD_LVL_RSP_XML)); + stubGetRequest(THIRD_LVL_A_FREESTYLE_JOB_IN_FOLDER_QUERY, EMPTY_FREESTYLE_JOB_BODY); + stubGetRequest(THIRD_LVL_A_MAVEN_JOB_IN_FOLDER_QUERY, EMPTY_MAVEN_JOB_BODY); + } + + private void stubFourthLevelResponse() { + stubGetRequest(FOURTH_LVL_B_FREESTYLE_JOB_IN_A_FOLDER_QUERY, EMPTY_FREESTYLE_JOB_BODY); + stubGetRequest(FOURTH_LVL_B_MAVEN_JOB_IN_A_FOLDER_QUERY, EMPTY_MAVEN_JOB_BODY); + } + + private void stubTopLevelConfigResponse() { + stubGetRequest(FOLDER_CONFIG_QUERY, getResponse(FOLDER_CONFIG)); + stubGetRequest(JOB_CONFIG_QUERY, getResponse(JOB_CONFIG)); + } + + private void stubSecondLevelConfigResponse() { + stubGetRequest(A_FOLDER_CONFIG_QUERY, getResponse(A_FOLDER_CONFIG)); + stubGetRequest(A_FREESTYLE_JOB_IN_FOLDER_CONFIG_QUERY, getResponse(A_FREESTYLE_JOB_IN_FOLDER_CONFIG)); + stubGetRequest(A_MAVEN_JOB_IN_FOLDER_CONFIG_QUERY, getResponse(A_MAVEN_JOB_IN_FOLDER_CONFIG)); + } + + private void stubThirdLevelConfigResponse() { + stubGetRequest(B_FREESTYLE_JOB_IN_FOLDER_CONFIG_QUERY, getResponse(B_FREESTYLE_JOB_IN_FOLDER_CONFIG)); + stubGetRequest(B_MAVEN_JOB_IN_FOLDER_CONFIG_QUERY, getResponse(B_MAVEN_JOB_IN_FOLDER_CONFIG)); + } + + private void stubGetRequest(String url, String template) { + stubFor(get(urlEqualTo(url)) + .willReturn(aResponse() + .withStatus(200) + .withBody(template))); + } + + public String getUrl() { + return url; + } + + public void verifyQueried() { + verifyGetRequest(TOP_LVL_QUERY); + verifyGetRequest(SECOND_LVL_FOLDER_QUERY); + verifyGetRequest(SECOND_LVL_JOB_QUERY); + verifyGetRequest(THIRD_LVL_A_FOLDER_QUERY); + verifyGetRequest(THIRD_LVL_A_FREESTYLE_JOB_IN_FOLDER_QUERY); + verifyGetRequest(THIRD_LVL_A_MAVEN_JOB_IN_FOLDER_QUERY); + verifyGetRequest(FOURTH_LVL_B_FREESTYLE_JOB_IN_A_FOLDER_QUERY); + verifyGetRequest(FOURTH_LVL_B_MAVEN_JOB_IN_A_FOLDER_QUERY); + } + + public void verifyImported() { + verifyGetRequest(FOLDER_CONFIG_QUERY); + verifyGetRequest(JOB_CONFIG_QUERY); + verifyGetRequest(A_FOLDER_CONFIG_QUERY); + verifyGetRequest(A_FREESTYLE_JOB_IN_FOLDER_CONFIG_QUERY); + verifyGetRequest(A_MAVEN_JOB_IN_FOLDER_CONFIG_QUERY); + verifyGetRequest(B_FREESTYLE_JOB_IN_FOLDER_CONFIG_QUERY); + verifyGetRequest(B_MAVEN_JOB_IN_FOLDER_CONFIG_QUERY); + } + + private void verifyGetRequest(String url) { + verify(getRequestedFor(urlEqualTo(url))); + } + + private static final String FIELD_START = "\\$\\{"; + private static final String FIELD_END = "\\}"; + private static final String REGEX = FIELD_START + "(baseUrl)" + FIELD_END; + + private String getResponse(String template) { + String rawXml = templateToString(template); + return rawXml.replaceAll(REGEX, url); + } + + private String templateToString(String template) { + try { + return IOUtils.toString(Thread.currentThread().getContextClassLoader().getResourceAsStream(template)); + } catch (IOException e) { + throw new RemoteJenkinsIOException(e.getMessage()); + } + } + + private static final class RemoteJenkinsIOException extends RuntimeException { + RemoteJenkinsIOException(String message) { + super(message); + } + } +} diff --git a/src/test/resources/README.md b/src/test/resources/README.md new file mode 100644 index 0000000..a22ebbf --- /dev/null +++ b/src/test/resources/README.md @@ -0,0 +1,19 @@ +``` +. +├── folder +│   ├── config.xml +│   └── jobs +│   ├── aFolder +│   │   ├── config.xml +│   │   └── jobs +│   │   ├── bFreestyleJobInFolder +│   │   │   ├── config.xml +│   │   └── bMavenJobInFolder +│   │   ├── config.xml +│   ├── aFreestyleJobInFolder +│   │   ├── config.xml +│   └── aMavenJobInFolder +│   ├── config.xml +├── job +│   ├── config.xml +``` \ No newline at end of file diff --git a/src/test/resources/folder/config.xml b/src/test/resources/folder/config.xml new file mode 100644 index 0000000..d085f4f --- /dev/null +++ b/src/test/resources/folder/config.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + All + false + false + + + + + + + + + true + true + true + true + false + + + + + \ No newline at end of file diff --git a/src/test/resources/folder/jobs/aFolder/config.xml b/src/test/resources/folder/jobs/aFolder/config.xml new file mode 100644 index 0000000..d085f4f --- /dev/null +++ b/src/test/resources/folder/jobs/aFolder/config.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + All + false + false + + + + + + + + + true + true + true + true + false + + + + + \ No newline at end of file diff --git a/src/test/resources/folder/jobs/aFolder/jobs/bFreestyleJobInFolder/config.xml b/src/test/resources/folder/jobs/aFolder/jobs/bFreestyleJobInFolder/config.xml new file mode 100644 index 0000000..9e076fb --- /dev/null +++ b/src/test/resources/folder/jobs/aFolder/jobs/bFreestyleJobInFolder/config.xml @@ -0,0 +1,50 @@ + + + + + false + + + false + + + + + + + + + + + + + false + + + false + + + false + false + + + 0 + 0 + + false + project + false + + + + + true + false + false + false + + false + + + + \ No newline at end of file diff --git a/src/test/resources/folder/jobs/aFolder/jobs/bMavenJobInFolder/config.xml b/src/test/resources/folder/jobs/aFolder/jobs/bMavenJobInFolder/config.xml new file mode 100644 index 0000000..e10d6b7 --- /dev/null +++ b/src/test/resources/folder/jobs/aFolder/jobs/bMavenJobInFolder/config.xml @@ -0,0 +1,73 @@ + + + + + false + + + false + + + + + + + + + + + + + false + + + false + + + false + false + + + 0 + 0 + + false + project + false + + + + + true + false + false + false + + false + true + false + false + false + false + false + false + false + false + -1 + false + false + true + + + + + + + + + FAILURE + 2 + RED + true + + \ No newline at end of file diff --git a/src/test/resources/folder/jobs/aFolder/xml-api-response.xml b/src/test/resources/folder/jobs/aFolder/xml-api-response.xml new file mode 100644 index 0000000..ed261e0 --- /dev/null +++ b/src/test/resources/folder/jobs/aFolder/xml-api-response.xml @@ -0,0 +1,12 @@ + + + + bFreestyleJobInFolder + ${baseUrl}/job/folder/job/aFolder/job/bFreestyleJobInFolder/ + + + + bMavenJobInFolder + ${baseUrl}/job/folder/job/aFolder/job/bMavenJobInFolder/ + + \ No newline at end of file diff --git a/src/test/resources/folder/jobs/aFreestyleJobInFolder/config.xml b/src/test/resources/folder/jobs/aFreestyleJobInFolder/config.xml new file mode 100644 index 0000000..9e076fb --- /dev/null +++ b/src/test/resources/folder/jobs/aFreestyleJobInFolder/config.xml @@ -0,0 +1,50 @@ + + + + + false + + + false + + + + + + + + + + + + + false + + + false + + + false + false + + + 0 + 0 + + false + project + false + + + + + true + false + false + false + + false + + + + \ No newline at end of file diff --git a/src/test/resources/folder/jobs/aMavenJobInFolder/config.xml b/src/test/resources/folder/jobs/aMavenJobInFolder/config.xml new file mode 100644 index 0000000..e10d6b7 --- /dev/null +++ b/src/test/resources/folder/jobs/aMavenJobInFolder/config.xml @@ -0,0 +1,73 @@ + + + + + false + + + false + + + + + + + + + + + + + false + + + false + + + false + false + + + 0 + 0 + + false + project + false + + + + + true + false + false + false + + false + true + false + false + false + false + false + false + false + false + -1 + false + false + true + + + + + + + + + FAILURE + 2 + RED + true + + \ No newline at end of file diff --git a/src/test/resources/folder/xml-api-response.xml b/src/test/resources/folder/xml-api-response.xml new file mode 100644 index 0000000..c0f18ed --- /dev/null +++ b/src/test/resources/folder/xml-api-response.xml @@ -0,0 +1,17 @@ + + + + aFolder + ${baseUrl}/job/folder/job/aFolder/ + + + + aFreestyleJobInFolder + ${baseUrl}/job/folder/job/aFreestyleJobInFolder/ + + + + aMavenJobInFolder + ${baseUrl}/job/folder/job/aMavenJobInFolder/ + + \ No newline at end of file diff --git a/src/test/resources/job/config.xml b/src/test/resources/job/config.xml new file mode 100644 index 0000000..e29817a --- /dev/null +++ b/src/test/resources/job/config.xml @@ -0,0 +1,97 @@ + + + + + false + + + false + + + + + false + + + https://github.com/Evildethow/test-ghpr-plugin/ + + + + false + + + false + false + + + 0 + 0 + + false + project + false + + + + + 2 + + + +refs/pull/*:refs/remotes/origin/pr/* + git@github.com:Evildethow/test-ghpr-plugin.git + 23dfb353-8d71-40d3-9773-314613f37221 + + + + + ${sha1} + + + false + + + + true + false + false + false + + + H/5 * * * * + 3 + 3 + + false + + H/5 * * * * + + false + false + false + + false + false + + + + + + fcad1491-7719-4dd5-8eb3-2d6da3503cac + + .*\[skip\W+ci\].* + + + + + + + false + + + + + false + + + + \ No newline at end of file diff --git a/src/test/resources/xml-api-response.xml b/src/test/resources/xml-api-response.xml new file mode 100644 index 0000000..3b19604 --- /dev/null +++ b/src/test/resources/xml-api-response.xml @@ -0,0 +1,12 @@ + + + + folder + ${baseUrl}/job/folder/ + + + + job + ${baseUrl}/job/job/ + + \ No newline at end of file