Apache License, Version 2.0
@@ -22,42 +32,41 @@
com.offbytwo.jenkins
jenkins-client
- 0.3.7-SNAPSHOT
+ ${jenkins.client.version}
org.jtwig
jtwig-core
- 5.65
+ ${jtwig.templates.version}
org.slf4j
slf4j-api
- 1.7.21
+ ${slf4j.api.version}
org.slf4j
slf4j-log4j12
- 1.7.21
+ ${slf4j-log4j12.version}
junit
junit
- 4.12
+ ${junit.version}
test
-
org.mockito
mockito-core
- 1.10.19
+ ${mockito-core.version}
test
org.assertj
assertj-core
- 3.6.1
+ ${assertj-core.version}
test
diff --git a/src/main/java/com/redhat/digkins/DiggerClient.java b/src/main/java/com/redhat/digkins/DiggerClient.java
index 5181816..abaf8ba 100644
--- a/src/main/java/com/redhat/digkins/DiggerClient.java
+++ b/src/main/java/com/redhat/digkins/DiggerClient.java
@@ -2,14 +2,17 @@
import com.offbytwo.jenkins.JenkinsServer;
import com.redhat.digkins.model.BuildStatus;
-import com.redhat.digkins.services.CreateJobService;
+import com.redhat.digkins.services.ArtifactsService;
+import com.redhat.digkins.services.JobService;
import com.redhat.digkins.services.TriggerBuildService;
import com.redhat.digkins.util.DiggerClientException;
import com.redhat.digkins.util.JenkinsAuth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
@@ -22,14 +25,19 @@ public class DiggerClient {
public static final long DEFAULT_BUILD_TIMEOUT = 60 * 1000;
- private final JenkinsServer jenkins;
+ private JenkinsServer jenkinsServer;
- public DiggerClient(JenkinsAuth auth) throws URISyntaxException {
- this.jenkins = new JenkinsServer(new URI(auth.getUrl()), auth.getUser(), auth.getPassword());
+ private JobService jobService;
+ private TriggerBuildService triggerBuildService;
+ private ArtifactsService artifactsService;
+
+ private DiggerClient() {
}
/**
- * Create client using provided url and credentials
+ * Create a client with defaults using provided url and credentials.
+ *
+ * This client will use the defaults for the services. This is perfectly fine for majorith of the cases.
*
* @param url Jenkins url
* @param user Jenkins user
@@ -37,15 +45,62 @@ public DiggerClient(JenkinsAuth auth) throws URISyntaxException {
* @return client instance
* @throws DiggerClientException if something goes wrong
*/
- public static DiggerClient from(String url, String user, String password) throws DiggerClientException {
- try {
- JenkinsAuth jenkinsAuth = new JenkinsAuth(url, user, password);
- return new DiggerClient(jenkinsAuth);
- } catch (URISyntaxException e) {
- throw new DiggerClientException("Invalid jenkins url format.");
+ public static DiggerClient createDefaultWithAuth(String url, String user, String password) throws DiggerClientException {
+ TriggerBuildService triggerBuildService = new TriggerBuildService(TriggerBuildService.DEFAULT_FIRST_CHECK_DELAY, TriggerBuildService.DEFAULT_POLL_PERIOD);
+ JobService jobService = new JobService();
+ ArtifactsService artifactsService = new ArtifactsService();
+ return DiggerClient.builder()
+ .createJobService(jobService)
+ .triggerBuildService(triggerBuildService)
+ .artifactsService(artifactsService)
+ .withAuth(url, user, password)
+ .build();
+ }
+
+ public static DiggerClientBuilder builder() {
+ return new DiggerClientBuilder();
+ }
+ public static class DiggerClientBuilder {
+ private JenkinsAuth auth;
+ private JobService jobService;
+ private TriggerBuildService triggerBuildService;
+ private ArtifactsService artifactsService;
+
+ public DiggerClientBuilder withAuth(String url, String user, String password) {
+ this.auth = new JenkinsAuth(url, user, password);
+ return this;
+ }
+
+ public DiggerClientBuilder createJobService(JobService jobService) {
+ this.jobService = jobService;
+ return this;
+ }
+
+ public DiggerClientBuilder triggerBuildService(TriggerBuildService triggerBuildService) {
+ this.triggerBuildService = triggerBuildService;
+ return this;
+ }
+
+ public DiggerClientBuilder artifactsService(ArtifactsService artifactsService) {
+ this.artifactsService = artifactsService;
+ return this;
+ }
+
+ public DiggerClient build() throws DiggerClientException {
+ final DiggerClient client = new DiggerClient();
+ try {
+ client.jenkinsServer = new JenkinsServer(new URI(auth.getUrl()), auth.getUser(), auth.getPassword());
+ client.jobService = this.jobService;
+ client.triggerBuildService = this.triggerBuildService;
+ client.artifactsService = this.artifactsService;
+ return client;
+ } catch (URISyntaxException e) {
+ throw new DiggerClientException("Invalid jenkins url format.");
+ }
}
}
+
/**
* Create new Digger job on Jenkins platform
*
@@ -55,9 +110,8 @@ public static DiggerClient from(String url, String user, String password) throws
* @throws DiggerClientException if something goes wrong
*/
public void createJob(String name, String gitRepo, String gitBranch) throws DiggerClientException {
- CreateJobService service = new CreateJobService(this.jenkins);
try {
- service.create(name, gitRepo, gitBranch);
+ jobService.create(this.jenkinsServer, name, gitRepo, gitBranch);
} catch (Throwable e) {
throw new DiggerClientException(e);
}
@@ -72,7 +126,7 @@ public void createJob(String name, String gitRepo, String gitBranch) throws Digg
* This method will block until there is a build number, or the given timeout period is passed. If the build is still in the queue
* after the given timeout period, a {@code BuildStatus} is returned with state {@link BuildStatus.State#TIMED_OUT}.
*
- * Please note that timeout period is never meant to be very precise. It has the resolution of {@link TriggerBuildService#POLL_PERIOD} because
+ * Please note that timeout period is never meant to be very precise. It has the resolution of {@link TriggerBuildService#DEFAULT_POLL_PERIOD} because
* timeout is checked before every pull.
*
* Similarly, {@link BuildStatus.State#CANCELLED_IN_QUEUE} is returned if the build is cancelled on Jenkins side and
@@ -80,14 +134,13 @@ public void createJob(String name, String gitRepo, String gitBranch) throws Digg
*
* @param jobName name of the job to trigger the build
* @param timeout how many milliseconds should this call block before returning {@link BuildStatus.State#TIMED_OUT}.
- * Should be larger than {@link TriggerBuildService#FIRST_CHECK_DELAY}
+ * Should be larger than {@link TriggerBuildService#DEFAULT_FIRST_CHECK_DELAY}
* @return the build status
* @throws DiggerClientException if connection problems occur during connecting to Jenkins
*/
public BuildStatus build(String jobName, long timeout) throws DiggerClientException {
- final TriggerBuildService triggerBuildService = new TriggerBuildService(jenkins);
try {
- return triggerBuildService.build(jobName, timeout);
+ return triggerBuildService.build(this.jenkinsServer, jobName, timeout);
} catch (IOException e) {
LOG.debug("Exception while connecting to Jenkins", e);
throw new DiggerClientException(e);
@@ -114,4 +167,32 @@ public BuildStatus build(String jobName) throws DiggerClientException {
return this.build(jobName, DEFAULT_BUILD_TIMEOUT);
}
+ /**
+ * Fetch artifacts urls for specific job and build number
+ *
+ * @param jobName name of the job
+ * @param buildNumber job build number
+ * @param artifactName - name of the artifact to fetch - can be regexp
+ * @return InputStream with file contents
+ * @throws DiggerClientException - when problem with fetching artifacts from jenkins
+ */
+ public InputStream fetchArtifact(String jobName, int buildNumber, String artifactName) throws DiggerClientException {
+ return artifactsService.streamArtifact(jenkinsServer,jobName, buildNumber, artifactName);
+ }
+
+ /**
+ * Save artifact for specified location for specific job, build number and artifact name.
+ * If name would be an regular expression method would return stream for the first match.
+ *
+ * @param jobName name of the job
+ * @param buildNumber job build number
+ * @param artifactName name of the artifact to fetch - can be regexp for example *.apk
+ * @param outputFile file (location) used to save artifact
+ *
+ * @throws DiggerClientException when problem with fetching artifacts from jenkins
+ * @throws IOException when one of the files cannot be saved
+ */
+ public void saveArtifact(String jobName, int buildNumber, String artifactName, File outputFile) throws DiggerClientException, IOException {
+ artifactsService.saveArtifact(jenkinsServer,jobName, buildNumber, artifactName,outputFile);
+ }
}
diff --git a/src/main/java/com/redhat/digkins/Main.java b/src/main/java/com/redhat/digkins/Main.java
new file mode 100644
index 0000000..7800df4
--- /dev/null
+++ b/src/main/java/com/redhat/digkins/Main.java
@@ -0,0 +1,36 @@
+package com.redhat.digkins;
+
+import com.redhat.digkins.services.JobService;
+import com.redhat.digkins.services.TriggerBuildService;
+import com.redhat.digkins.util.DiggerClientException;
+import org.apache.commons.io.IOUtils;
+
+import java.io.*;
+
+/**
+ */
+public class Main {
+
+ public static void main(String[] args) throws DiggerClientException, IOException {
+ DiggerClient client = DiggerClient.builder()
+ .createJobService(new JobService())
+ .triggerBuildService(new TriggerBuildService(10000, 100))
+ .withAuth("https://jenkins-digger2.osm3.feedhenry.net", "admin", "Vu8ysYH5f2dJiLgL")
+ .build();
+ //client.createJob("wtr-java-tests2", "https://github.com/wtrocki/helloworld-android-gradle", "master");
+ //client.build("wtr-java-tests2");
+ InputStream inputStream = client.fetchArtifact("wtr-java-tests2", 1, "app-debug.apk");
+ if(inputStream != null){
+ File targetFile = new File("artifact.tmp");
+ OutputStream outStream = new FileOutputStream(targetFile);
+
+ byte[] buffer = new byte[8 * 1024];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outStream.write(buffer, 0, bytesRead);
+ }
+ IOUtils.closeQuietly(inputStream);
+ IOUtils.closeQuietly(outStream);
+ }
+ }
+}
diff --git a/src/main/java/com/redhat/digkins/services/ArtifactsService.java b/src/main/java/com/redhat/digkins/services/ArtifactsService.java
new file mode 100644
index 0000000..68efca8
--- /dev/null
+++ b/src/main/java/com/redhat/digkins/services/ArtifactsService.java
@@ -0,0 +1,94 @@
+package com.redhat.digkins.services;
+
+import com.offbytwo.jenkins.JenkinsServer;
+import com.offbytwo.jenkins.model.Artifact;
+import com.offbytwo.jenkins.model.Build;
+import com.offbytwo.jenkins.model.BuildWithDetails;
+import com.offbytwo.jenkins.model.JobWithDetails;
+import com.redhat.digkins.util.DiggerClientException;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.URISyntaxException;
+import java.util.List;
+
+/**
+ * Service used to retrieve artifacts
+ */
+public class ArtifactsService {
+
+ /**
+ */
+ public ArtifactsService() {
+ }
+
+ private static final Logger LOG = LoggerFactory.getLogger(ArtifactsService.class);
+ private static int DEFAULT_BUFFER = 8 * 1024;
+
+ /**
+ * Save artifact for specified location for specific job, build number and artifact name.
+ * If name would be an regular expression method would return stream for the first match.
+ *
+ * @param jobName name of the job
+ * @param buildNumber job build number
+ * @param artifactName name of the artifact to fetch - can be regexp for example *.apk
+ * @param outputFile file (location) used to save artifact
+ * @throws DiggerClientException when problem with fetching artifacts from jenkins
+ * @throws IOException when one of the files cannot be saved
+ */
+ public void saveArtifact(JenkinsServer jenkins, String jobName, int buildNumber, String artifactName, File outputFile) throws DiggerClientException, IOException {
+ InputStream inputStream = streamArtifact(jenkins, jobName, buildNumber, artifactName);
+ if (inputStream != null) {
+ OutputStream outStream = new FileOutputStream(outputFile);
+ byte[] buffer = new byte[DEFAULT_BUFFER];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outStream.write(buffer, 0, bytesRead);
+ }
+ IOUtils.closeQuietly(inputStream);
+ IOUtils.closeQuietly(outStream);
+ } else {
+ throw new DiggerClientException("Cannot fetch artifacts from jenkins");
+ }
+ }
+
+ /**
+ * Get artifact inputstream for specific job, build number and artifact name.
+ * If name would be an regular expression method would return stream for the first match.
+ *
+ * @param jobName name of the job
+ * @param buildNumber job build number
+ * @param artifactName name of the artifact to fetch - can be regexp for example *.apk
+ * @return InputStream with file contents that can be saved or piped to socket
+ * @throws DiggerClientException when problem with fetching artifacts from jenkins
+ */
+ public InputStream streamArtifact(JenkinsServer jenkins, String jobName, int buildNumber, String artifactName) throws DiggerClientException {
+ try {
+ JobWithDetails job = jenkins.getJob(jobName);
+ if (job == null) {
+ LOG.error("Cannot fetch job from jenkins {0}", jobName);
+ throw new DiggerClientException("Cannot fetch job from jenkins");
+ }
+ Build build = job.getBuildByNumber(buildNumber);
+ BuildWithDetails buildWithDetails = build.details();
+ List artifacts = buildWithDetails.getArtifacts();
+ for (Artifact artifact : artifacts) {
+ if (artifact.getFileName().matches(artifactName)) {
+ LOG.debug("Streaming artifact {0}", artifactName);
+ return buildWithDetails.downloadArtifact(artifact);
+ }
+ }
+ } catch (URISyntaxException e) {
+ LOG.error("Invalid job name {0}", jobName, e);
+ throw new DiggerClientException(e);
+ } catch (IOException e) {
+ LOG.error("Problem when fetching artifacts for {0} {1} {2}", jobName, buildNumber, artifactName, e);
+ throw new DiggerClientException(e);
+ }
+ LOG.debug("Cannot find build for ", jobName, buildNumber, artifactName);
+ return null;
+ }
+
+}
diff --git a/src/main/java/com/redhat/digkins/services/CreateJobService.java b/src/main/java/com/redhat/digkins/services/CreateJobService.java
deleted file mode 100644
index 6d37a48..0000000
--- a/src/main/java/com/redhat/digkins/services/CreateJobService.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.redhat.digkins.services;
-
-import com.offbytwo.jenkins.JenkinsServer;
-import org.jtwig.JtwigModel;
-import org.jtwig.JtwigTemplate;
-
-import java.io.IOException;
-
-/**
- * Create digger job on jenkins platform
- */
-public class CreateJobService {
-
- private final static String GIT_REPO_URL = "GIT_REPO_URL";
- private final static String GIT_REPO_BRANCH = "GIT_REPO_BRANCH";
-
- private JenkinsServer jenkins;
-
- /**
- * @param jenkins jenkins api instance
- */
- public CreateJobService(JenkinsServer jenkins) {
- this.jenkins = jenkins;
- }
-
- /**
- * Create new digger job on jenkins platform
- *
- * @param name job name that can be used later to reference job
- * @param gitRepo git repository url (full git repository url. e.g git@github.com:digger/helloworld.git
- * @param gitBranch git repository branch (default branch used to checkout source code)
- */
- public void create(String name, String gitRepo, String gitBranch) throws IOException {
- JtwigTemplate template = JtwigTemplate.classpathTemplate("templates/job.xml");
- JtwigModel model = JtwigModel.newModel().with(GIT_REPO_URL, gitRepo).with(GIT_REPO_BRANCH, gitBranch);
- jenkins.createJob(name, template.render(model));
- }
-
-}
diff --git a/src/main/java/com/redhat/digkins/services/JobService.java b/src/main/java/com/redhat/digkins/services/JobService.java
new file mode 100644
index 0000000..521fc1d
--- /dev/null
+++ b/src/main/java/com/redhat/digkins/services/JobService.java
@@ -0,0 +1,31 @@
+package com.redhat.digkins.services;
+
+import com.offbytwo.jenkins.JenkinsServer;
+import org.jtwig.JtwigModel;
+import org.jtwig.JtwigTemplate;
+
+import java.io.IOException;
+
+/**
+ * Create digger job on jenkins platform
+ */
+public class JobService {
+
+ private final static String GIT_REPO_URL = "GIT_REPO_URL";
+ private final static String GIT_REPO_BRANCH = "GIT_REPO_BRANCH";
+ private static final String JOB_TEMPLATE_PATH = "templates/job.xml";
+
+ /**
+ * Create new digger job on jenkins platform
+ *
+ * @param jenkinsServer Jenkins server client
+ * @param name job name that can be used later to reference job
+ * @param gitRepo git repository url (full git repository url. e.g git@github.com:digger/helloworld.git
+ * @param gitBranch git repository branch (default branch used to checkout source code)
+ */
+ public void create(JenkinsServer jenkinsServer, String name, String gitRepo, String gitBranch) throws IOException {
+ JtwigTemplate template = JtwigTemplate.classpathTemplate(JOB_TEMPLATE_PATH);
+ JtwigModel model = JtwigModel.newModel().with(GIT_REPO_URL, gitRepo).with(GIT_REPO_BRANCH, gitBranch);
+ jenkinsServer.createJob(name, template.render(model));
+ }
+}
diff --git a/src/main/java/com/redhat/digkins/services/TriggerBuildService.java b/src/main/java/com/redhat/digkins/services/TriggerBuildService.java
index 3857dc2..68864f9 100644
--- a/src/main/java/com/redhat/digkins/services/TriggerBuildService.java
+++ b/src/main/java/com/redhat/digkins/services/TriggerBuildService.java
@@ -19,36 +19,40 @@ public class TriggerBuildService {
private static final Logger LOG = LoggerFactory.getLogger(TriggerBuildService.class);
/**
- * How long should we wait before we start checking the queue item status.
+ * Default value of {@link #firstCheckDelay}
*/
- public static final long FIRST_CHECK_DELAY = 5 * 1000L;
+ public static final long DEFAULT_FIRST_CHECK_DELAY = 5 * 1000L;
/**
- * How long should we wait before checking the queue item status for next time.
+ * Default value of {@link #pollPeriod}
*/
- public static final long POLL_PERIOD = 2 * 1000L;
+ public static final long DEFAULT_POLL_PERIOD = 2 * 1000L;
- private JenkinsServer jenkinsServer;
+ private long firstCheckDelay;
+ private long pollPeriod;
/**
- * @param jenkinsServer jenkins api instance
+ * @param firstCheckDelay how long should we wait (in milliseconds) before we start checking the queue item status
+ * @param pollPeriod how long should we wait (in milliseconds) before checking the queue item status for next time
*/
- public TriggerBuildService(JenkinsServer jenkinsServer) {
- this.jenkinsServer = jenkinsServer;
+ public TriggerBuildService(long firstCheckDelay, long pollPeriod) {
+ this.firstCheckDelay = firstCheckDelay;
+ this.pollPeriod = pollPeriod;
}
/**
* See the documentation in {@link com.redhat.digkins.DiggerClient#build(String, long)}
*
- * @param jobName name of the job
- * @param timeout timeout
+ * @param jenkinsServer Jenkins server client
+ * @param jobName name of the job
+ * @param timeout timeout
* @return the build status
* @throws IOException if connection problems occur during connecting to Jenkins
* @throws InterruptedException if a problem occurs during sleeping between checks
* @see com.redhat.digkins.DiggerClient#build(String, long)
*/
- public BuildStatus build(String jobName, long timeout) throws IOException, InterruptedException {
+ public BuildStatus build(JenkinsServer jenkinsServer, String jobName, long timeout) throws IOException, InterruptedException {
final long whenToTimeout = System.currentTimeMillis() + timeout;
LOG.debug("Going to build job with name: {}", jobName);
@@ -72,8 +76,8 @@ public BuildStatus build(String jobName, long timeout) throws IOException, Inter
// do it until we have an executable.
// we would have an executable when the build leaves queue and starts building.
- LOG.debug("Going to sleep {} msecs", FIRST_CHECK_DELAY);
- Thread.sleep(FIRST_CHECK_DELAY);
+ LOG.debug("Going to sleep {} msecs", firstCheckDelay);
+ Thread.sleep(firstCheckDelay);
QueueItem queueItem;
while (true) {
@@ -107,8 +111,8 @@ public BuildStatus build(String jobName, long timeout) throws IOException, Inter
} else {
LOG.debug("Build did not start executing yet.");
if (whenToTimeout > System.currentTimeMillis()) {
- LOG.debug("Timeout period has not exceeded yet. Sleeping for {} msecs", POLL_PERIOD);
- Thread.sleep(POLL_PERIOD);
+ LOG.debug("Timeout period has not exceeded yet. Sleeping for {} msecs", pollPeriod);
+ Thread.sleep(pollPeriod);
} else {
LOG.debug("Timeout period has exceeded. Returning TIMED_OUT.");
return new BuildStatus(BuildStatus.State.TIMED_OUT, -1);
diff --git a/src/test/java/com/redhat/digkins/services/ArtifactsServiceTests.java b/src/test/java/com/redhat/digkins/services/ArtifactsServiceTests.java
new file mode 100644
index 0000000..59d4fc2
--- /dev/null
+++ b/src/test/java/com/redhat/digkins/services/ArtifactsServiceTests.java
@@ -0,0 +1,87 @@
+package com.redhat.digkins.services;
+
+import com.offbytwo.jenkins.JenkinsServer;
+import com.offbytwo.jenkins.model.*;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ArtifactsServiceTests {
+
+ @Mock
+ private JenkinsServer server;
+ private ArtifactsService artifactsService;
+
+ @Before
+ public void beforeTests() {
+ artifactsService = new ArtifactsService();
+ }
+
+ @Test
+ public void shouldFetchArtifactsWithNoResults() throws Exception {
+ BuildWithDetails build = mock(BuildWithDetails.class);
+ JobWithDetails job = mock(JobWithDetails.class);
+ when(server.getJob(anyString())).thenReturn(job);
+ when(job.getBuildByNumber(anyInt())).thenReturn(build);
+ when(build.details()).thenReturn(build);
+ InputStream artifact = artifactsService.streamArtifact(server, "artifact", 1, "test");
+
+ assertNull(artifact);
+ }
+
+ @Test
+ public void shouldFetchArtifactsWithResults() throws Exception {
+ Artifact artifact = mock(Artifact.class);
+ JobWithDetails job = mock(JobWithDetails.class);
+ BuildWithDetails build = mock(BuildWithDetails.class);
+ FileInputStream fs = mock(FileInputStream.class);
+ when(server.getJob(anyString())).thenReturn(job);
+ when(job.getBuildByNumber(anyInt())).thenReturn(build);
+ when(build.details()).thenReturn(build);
+ when(build.getArtifacts()).thenReturn(Arrays.asList(artifact));
+ when(build.downloadArtifact(artifact)).thenReturn(fs);
+ String artifactName = "test";
+ when(artifact.getFileName()).thenReturn(artifactName);
+ InputStream artifactStream = artifactsService.streamArtifact(server, "artifact", 1, artifactName);
+
+ assertThat(artifactStream).isNotNull();
+ }
+
+
+ @Test
+ public void shouldSaveFileArtifactWithResults() throws Exception {
+ Artifact artifact = mock(Artifact.class);
+ FileInputStream fs = mock(FileInputStream.class);
+ JobWithDetails job = mock(JobWithDetails.class);
+ BuildWithDetails build = mock(BuildWithDetails.class);
+ String artifactName = "test";
+ when(server.getJob(anyString())).thenReturn(job);
+ when(job.getBuildByNumber(anyInt())).thenReturn(build);
+ when(build.details()).thenReturn(build);
+ when(build.getArtifacts()).thenReturn(Arrays.asList(artifact));
+ when(artifact.getFileName()).thenReturn(artifactName);
+ when(build.downloadArtifact(artifact)).thenReturn(fs);
+ when(fs.read(Matchers.anyObject())).thenReturn(-1);
+ when(build.details()).thenReturn(build);
+ File outputFile = new File("test.out");
+ artifactsService.saveArtifact(server, "artifact", 1, artifactName, outputFile);
+
+ assertThat(outputFile.exists()).isTrue();
+ outputFile.delete();
+ }
+}
diff --git a/src/test/java/com/redhat/digkins/services/JobServiceTests.java b/src/test/java/com/redhat/digkins/services/JobServiceTests.java
new file mode 100644
index 0000000..96bc0cc
--- /dev/null
+++ b/src/test/java/com/redhat/digkins/services/JobServiceTests.java
@@ -0,0 +1,39 @@
+package com.redhat.digkins.services;
+
+import com.offbytwo.jenkins.JenkinsServer;
+import com.offbytwo.jenkins.model.BuildWithDetails;
+import com.offbytwo.jenkins.model.JobWithDetails;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.*;
+
+@RunWith(MockitoJUnitRunner.class)
+public class JobServiceTests {
+
+ @Mock
+ private JenkinsServer server;
+ private JobService jobService;
+
+ @Before
+ public void beforeTests() {
+ jobService = new JobService();
+ }
+
+ @Test
+ public void shouldCreateJob() throws Exception {
+ JobWithDetails job = mock(JobWithDetails.class);
+ BuildWithDetails build = mock(BuildWithDetails.class);
+ when(job.getBuildByNumber(anyInt())).thenReturn(build);
+ when(build.details()).thenReturn(build);
+ jobService.create(server, "name", "repo", "branch");
+ verify(server, times(1)).createJob(anyString(), anyString());
+ }
+
+}
diff --git a/src/test/java/com/redhat/digkins/services/TriggerBuildServiceTest.java b/src/test/java/com/redhat/digkins/services/TriggerBuildServiceTest.java
index 52fd7f6..247bdad 100644
--- a/src/test/java/com/redhat/digkins/services/TriggerBuildServiceTest.java
+++ b/src/test/java/com/redhat/digkins/services/TriggerBuildServiceTest.java
@@ -11,11 +11,10 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-
-import static org.assertj.core.api.Assertions.*;
-
import org.mockito.runners.MockitoJUnitRunner;
+import static org.assertj.core.api.Assertions.assertThat;
+
@RunWith(MockitoJUnitRunner.class)
public class TriggerBuildServiceTest {
@@ -32,27 +31,27 @@ public class TriggerBuildServiceTest {
@Before
public void setUp() throws Exception {
- service = new TriggerBuildService(jenkinsServer);
+ service = new TriggerBuildService(300, 50); // wait for 300 msecs for initial build, check every 50 msecs
Mockito.when(jenkinsServer.getJob("TEST")).thenReturn(mockJob);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfJobCannotBeFound() throws Exception {
- service.build("UNKNOWN", 10000);
+ service.build(jenkinsServer, "UNKNOWN", 10000);
}
@Test(expected = IllegalStateException.class)
public void shouldThrowExceptionIfJenkinsDoesNotReturnQueueReference() throws Exception {
Mockito.when(mockJob.build()).thenReturn(null);
- service.build("TEST", 10000);
+ service.build(jenkinsServer, "TEST", 10000);
}
@Test(expected = IllegalStateException.class)
public void shouldThrowExceptionIfQueueItemIsNullForReference() throws Exception {
Mockito.when(mockJob.build()).thenReturn(queueReference);
Mockito.when(jenkinsServer.getQueueItem(queueReference)).thenReturn(null);
- service.build("TEST", 10000);
+ service.build(jenkinsServer, "TEST", 10000);
}
@Test
@@ -63,7 +62,7 @@ public void shouldReturnCancelledStatus() throws Exception {
Mockito.when(mockJob.build()).thenReturn(queueReference);
Mockito.when(jenkinsServer.getQueueItem(queueReference)).thenReturn(queueItem);
- final BuildStatus buildStatus = service.build("TEST", 10000);
+ final BuildStatus buildStatus = service.build(jenkinsServer, "TEST", 10000);
assertThat(buildStatus).isNotNull();
assertThat(buildStatus.getState()).isEqualTo(BuildStatus.State.CANCELLED_IN_QUEUE);
}
@@ -76,7 +75,7 @@ public void shouldReturnStuckStatus() throws Exception {
Mockito.when(mockJob.build()).thenReturn(queueReference);
Mockito.when(jenkinsServer.getQueueItem(queueReference)).thenReturn(queueItem);
- final BuildStatus buildStatus = service.build("TEST", 10000);
+ final BuildStatus buildStatus = service.build(jenkinsServer, "TEST", 10000);
assertThat(buildStatus).isNotNull();
assertThat(buildStatus.getState()).isEqualTo(BuildStatus.State.STUCK_IN_QUEUE);
}
@@ -90,7 +89,7 @@ public void shouldReturnBuildNumber() throws Exception {
Mockito.when(mockJob.build()).thenReturn(queueReference);
Mockito.when(jenkinsServer.getQueueItem(queueReference)).thenReturn(queueItem);
- final BuildStatus buildStatus = service.build("TEST", 10000);
+ final BuildStatus buildStatus = service.build(jenkinsServer, "TEST", 10000);
assertThat(buildStatus).isNotNull();
assertThat(buildStatus.getState()).isEqualTo(BuildStatus.State.BUILDING);
@@ -108,7 +107,7 @@ public void shouldReturnBuildNumber_whenDidNotStartExecutingImmediately() throws
Mockito.when(mockJob.build()).thenReturn(queueReference);
// return `not-building` for the first 2 checks, then return `building`
Mockito.when(jenkinsServer.getQueueItem(queueReference)).thenReturn(queueItemNotBuildingYet, queueItemNotBuildingYet, queueItemBuilding);
- final BuildStatus buildStatus = service.build("TEST", 20000L);
+ final BuildStatus buildStatus = service.build(jenkinsServer, "TEST", 10000L);
assertThat(buildStatus).isNotNull();
assertThat(buildStatus.getState()).isEqualTo(BuildStatus.State.BUILDING);
@@ -123,7 +122,7 @@ public void shouldReturnTimeout() throws Exception {
Mockito.when(mockJob.build()).thenReturn(queueReference);
Mockito.when(jenkinsServer.getQueueItem(queueReference)).thenReturn(queueItemNotBuildingYet);
- final BuildStatus buildStatus = service.build("TEST", 10000L);
+ final BuildStatus buildStatus = service.build(jenkinsServer, "TEST", 500L);
assertThat(buildStatus).isNotNull();
assertThat(buildStatus.getState()).isEqualTo(BuildStatus.State.TIMED_OUT);