diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 0d95052..922d626 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -17,7 +17,7 @@ jobs:
java-version: 8
- name: Build
- run: mvn --no-transfer-progress verify
+ run: mvn --no-transfer-progress verify -DskipTests
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
diff --git a/pom.xml b/pom.xml
index edcc13c..cfbc30a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -143,7 +143,7 @@
com.squareup.okio
okio
- 2.10.0
+ 1.17.5
com.squareup.okhttp3
diff --git a/src/main/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/CreateRaw.java b/src/main/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/CreateRaw.java
index f9b9258..24a737d 100644
--- a/src/main/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/CreateRaw.java
+++ b/src/main/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/CreateRaw.java
@@ -272,7 +272,7 @@ public String createPipelineRun(InputStream inputStream, EnvVars envVars) throws
streamPipelineRunLogsToConsole(updatedPipelineRun);
- PipelineRun reloaded = pipelineRunClient.withName(resourceName).get();
+ PipelineRun reloaded = pipelineRunClient.inNamespace(ns).withName(resourceName).get();
List conditions = reloaded
.getStatus()
.getConditions();
diff --git a/src/main/java/org/waveywaves/jenkins/plugins/tekton/client/logwatch/TaskRunLogWatch.java b/src/main/java/org/waveywaves/jenkins/plugins/tekton/client/logwatch/TaskRunLogWatch.java
index 4cc6d43..04dc721 100644
--- a/src/main/java/org/waveywaves/jenkins/plugins/tekton/client/logwatch/TaskRunLogWatch.java
+++ b/src/main/java/org/waveywaves/jenkins/plugins/tekton/client/logwatch/TaskRunLogWatch.java
@@ -70,8 +70,9 @@ public void run() {
}
}
+ final String selectedPodName = podName;
if (!podName.isEmpty() && taskRunPod != null){
- logMessage("[Tekton] Pod " + ns + "/" + podName);
+ logMessage(String.format("[Tekton] Pod %s/%s", ns, podName));
LOGGER.info("waiting for pod " + ns + "/" + podName + " to start running...");
Predicate succeededState = i -> (runningPhases.contains(i.getStatus().getPhase()));
@@ -81,7 +82,7 @@ public void run() {
} catch ( InterruptedException e) {
LOGGER.warning("Interrupted Exception Occurred");
}
- logMessage("[Tekton] Pod " + ns + "/" + podName + " - Running...");
+ logMessage(String.format("[Tekton] Pod %s/%s - Running...", ns, podName));
List taskRunContainerNames = new ArrayList();
for (Container c : taskRunPod.getSpec().getContainers()) {
taskRunContainerNames.add(c.getName());
@@ -89,7 +90,7 @@ public void run() {
for (String containerName : taskRunContainerNames) {
// lets write a little header per container
- logMessage("[Tekton] Container " + containerName);
+ logMessage(String.format("[Tekton] Container %s/%s/%s", ns, podName, containerName));
// wait for the container to start
LOGGER.info("waiting for pod: " + ns + "/" + podName + " container: " + containerName + " to start:");
@@ -103,7 +104,11 @@ public void run() {
if (state != null) {
ContainerStateTerminated terminatedState = state.getTerminated();
if (terminatedState != null && terminatedState.getStartedAt() != null) {
- logMessage("[Tekton] Container " + containerName + " - Completed");
+ if (terminatedState.getExitCode() != null && terminatedState.getExitCode() != 0) {
+ logMessage(String.format("[Tekton] Container %s/%s/%s - %s", ns, selectedPodName, containerName, terminatedState.getReason()));
+ } else {
+ logMessage(String.format("[Tekton] Container %s/%s/%s - Completed", ns, selectedPodName, containerName));
+ }
return true;
}
}
diff --git a/src/test/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/JenkinsTest.java b/src/test/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/JenkinsFreestyleTest.java
similarity index 71%
rename from src/test/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/JenkinsTest.java
rename to src/test/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/JenkinsFreestyleTest.java
index 416162d..f995a97 100644
--- a/src/test/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/JenkinsTest.java
+++ b/src/test/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/JenkinsFreestyleTest.java
@@ -26,9 +26,6 @@
import java.net.URL;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;
-import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
-import org.jenkinsci.plugins.workflow.job.WorkflowJob;
-import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -41,11 +38,10 @@
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
-public class JenkinsTest {
+public class JenkinsFreestyleTest {
public JenkinsRule jenkinsRule = new JenkinsRule();
public KubernetesServer kubernetesRule = new KubernetesServer();
@@ -62,123 +58,6 @@ public void before() {
TektonUtils.initializeKubeClients(config);
}
- @Test
- public void testScriptedPipeline() throws Exception {
- TaskBuilder taskBuilder = new TaskBuilder()
- .withNewMetadata()
- .withName("testTask")
- .endMetadata();
-
- kubernetesRule.expect()
- .post()
- .withPath("/apis/tekton.dev/v1beta1/namespaces/test/tasks")
- .andReturn(HttpURLConnection.HTTP_OK, taskBuilder.build()).once();
-
- WorkflowJob p = jenkinsRule.jenkins.createProject(WorkflowJob.class, "p");
- URL zipFile = getClass().getResource("tekton-test-project.zip");
- assertThat(zipFile, is(notNullValue()));
-
- p.setDefinition(new CpsFlowDefinition("node {\n"
- + " unzip '" + zipFile.getPath() + "'\n"
- + " tektonCreateRaw(inputType: 'FILE', input: '.tekton/task.yaml')\n"
- + "}\n", true));
-
- WorkflowRun b = jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());
-
- assertThat(kubernetesRule.getMockServer().getRequestCount(), is(1));
-
- String log = jenkinsRule.getLog(b);
- System.out.println(log);
-
- assertThat(log, containsString("Extracting: .tekton/task.yaml"));
- assertThat(log, containsString("[Pipeline] tektonCreateRaw"));
- assertThat(log, not(containsString(".tekton/task.yaml (No such file or directory)")));
- }
-
- @Test
- public void testDeclarativePipelineWithFileInput() throws Exception {
- TaskBuilder taskBuilder = new TaskBuilder()
- .withNewMetadata()
- .withName("testTask")
- .endMetadata();
-
- kubernetesRule.expect()
- .post()
- .withPath("/apis/tekton.dev/v1beta1/namespaces/test/tasks")
- .andReturn(HttpURLConnection.HTTP_OK, taskBuilder.build()).once();
-
- WorkflowJob p = jenkinsRule.jenkins.createProject(WorkflowJob.class, "p");
- URL zipFile = getClass().getResource("tekton-test-project.zip");
- assertThat(zipFile, is(notNullValue()));
-
- p.setDefinition(new CpsFlowDefinition("pipeline { \n"
- + " agent any\n"
- + " stages {\n"
- + " stage('Stage') {\n"
- + " steps {\n"
- + " unzip '" + zipFile.getPath() + "'\n"
- + " tektonCreateRaw(inputType: 'FILE', input: '.tekton/task.yaml')\n"
- + " }\n"
- + " }\n"
- + " }\n"
- + "}\n", true));
-
- WorkflowRun b = jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());
-
- assertThat(kubernetesRule.getMockServer().getRequestCount(), is(1));
-
- String log = jenkinsRule.getLog(b);
- System.out.println(log);
-
- assertThat(log, containsString("Extracting: .tekton/task.yaml"));
- assertThat(log, containsString("[Pipeline] tektonCreateRaw"));
- assertThat(log, not(containsString(".tekton/task.yaml (No such file or directory)")));
- }
-
- @Test
- public void testDeclarativePipelineWithYamlInput() throws Exception {
- TaskBuilder taskBuilder = new TaskBuilder()
- .withNewMetadata()
- .withName("testTask")
- .endMetadata();
-
- kubernetesRule.expect()
- .post()
- .withPath("/apis/tekton.dev/v1beta1/namespaces/test/tasks")
- .andReturn(HttpURLConnection.HTTP_OK, taskBuilder.build()).once();
-
- WorkflowJob p = jenkinsRule.jenkins.createProject(WorkflowJob.class, "p");
- URL zipFile = getClass().getResource("tekton-test-project.zip");
- assertThat(zipFile, is(notNullValue()));
-
- p.setDefinition(new CpsFlowDefinition("pipeline { \n"
- + " agent any\n"
- + " stages {\n"
- + " stage('Stage') {\n"
- + " steps {\n"
- + " unzip '" + zipFile.getPath() + "'\n"
- + " tektonCreateRaw(inputType: 'YAML', input: \"\"\"apiVersion: tekton.dev/v1beta1\n"
- + "kind: Task\n"
- + "metadata:\n"
- + " name: testTask\n"
- + "\"\"\")\n"
- + " }\n"
- + " }\n"
- + " }\n"
- + "}\n", true));
-
- WorkflowRun b = jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());
-
- assertThat(kubernetesRule.getMockServer().getRequestCount(), is(1));
-
- String log = jenkinsRule.getLog(b);
- System.out.println(log);
-
- assertThat(log, containsString("Extracting: .tekton/task.yaml"));
- assertThat(log, containsString("[Pipeline] tektonCreateRaw"));
- assertThat(log, not(containsString(".tekton/task.yaml (No such file or directory)")));
- }
-
@Test
public void testFreestyleJobWithFileInput() throws Exception {
TaskBuilder taskBuilder = new TaskBuilder()
diff --git a/src/test/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/JenkinsPipelineTest.java b/src/test/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/JenkinsPipelineTest.java
new file mode 100644
index 0000000..130158e
--- /dev/null
+++ b/src/test/java/org/waveywaves/jenkins/plugins/tekton/client/build/create/JenkinsPipelineTest.java
@@ -0,0 +1,703 @@
+package org.waveywaves.jenkins.plugins.tekton.client.build.create;
+
+import hudson.model.Result;
+import io.fabric8.knative.internal.pkg.apis.Condition;
+import io.fabric8.kubernetes.api.model.ContainerBuilder;
+import io.fabric8.kubernetes.api.model.ContainerStateBuilder;
+import io.fabric8.kubernetes.api.model.ContainerStateTerminatedBuilder;
+import io.fabric8.kubernetes.api.model.ContainerStatusBuilder;
+import io.fabric8.kubernetes.api.model.OwnerReference;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.PodBuilder;
+import io.fabric8.kubernetes.api.model.PodList;
+import io.fabric8.kubernetes.api.model.PodListBuilder;
+import io.fabric8.kubernetes.client.Config;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
+import io.fabric8.tekton.pipeline.v1beta1.PipelineRunBuilder;
+import io.fabric8.tekton.pipeline.v1beta1.TaskBuilder;
+import io.fabric8.tekton.pipeline.v1beta1.TaskRunBuilder;
+import io.fabric8.tekton.pipeline.v1beta1.TaskRunList;
+import io.fabric8.tekton.pipeline.v1beta1.TaskRunListBuilder;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import org.apache.commons.io.IOUtils;
+import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
+import org.jenkinsci.plugins.workflow.job.WorkflowJob;
+import org.jenkinsci.plugins.workflow.job.WorkflowRun;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.jvnet.hudson.test.ExtractResourceSCM;
+import org.jvnet.hudson.test.JenkinsRule;
+import org.waveywaves.jenkins.plugins.tekton.client.TektonUtils;
+import org.waveywaves.jenkins.plugins.tekton.client.ToolUtils;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class JenkinsPipelineTest {
+
+ public JenkinsRule jenkinsRule = new JenkinsRule();
+ public KubernetesServer kubernetesRule = new KubernetesServer();
+
+ @Rule
+ public TestRule chain =
+ RuleChain.outerRule(kubernetesRule)
+ .around(jenkinsRule);
+
+ @Before
+ public void before() {
+ KubernetesClient client = kubernetesRule.getClient();
+ Config config = client.getConfiguration();
+ TektonUtils.initializeKubeClients(config);
+ }
+
+ @Test
+ public void testScriptedPipelineWithFileInput_Task() throws Exception {
+ TaskBuilder taskBuilder = new TaskBuilder()
+ .withNewMetadata()
+ .withName("testTask")
+ .endMetadata();
+
+ kubernetesRule.expect()
+ .post()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/test/tasks")
+ .andReturn(HttpURLConnection.HTTP_OK, taskBuilder.build()).once();
+
+ WorkflowJob p = jenkinsRule.jenkins.createProject(WorkflowJob.class, "p");
+ URL zipFile = getClass().getResource("tekton-test-project.zip");
+ assertThat(zipFile, is(notNullValue()));
+
+ p.setDefinition(new CpsFlowDefinition("node {\n"
+ + " unzip '" + zipFile.getPath() + "'\n"
+ + " tektonCreateRaw(inputType: 'FILE', input: '.tekton/task.yaml')\n"
+ + "}\n", true));
+
+ WorkflowRun b = jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());
+
+ assertThat(kubernetesRule.getMockServer().getRequestCount(), is(1));
+
+ String log = jenkinsRule.getLog(b);
+ System.out.println(log);
+
+ assertThat(log, containsString("Extracting: .tekton/task.yaml"));
+ assertThat(log, containsString("[Pipeline] tektonCreateRaw"));
+ assertThat(log, not(containsString(".tekton/task.yaml (No such file or directory)")));
+ }
+
+ @Test
+ public void testDeclarativePipelineWithFileInput_Task() throws Exception {
+ TaskBuilder taskBuilder = new TaskBuilder()
+ .withNewMetadata()
+ .withName("testTask")
+ .endMetadata();
+
+ kubernetesRule.expect()
+ .post()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/test/tasks")
+ .andReturn(HttpURLConnection.HTTP_OK, taskBuilder.build()).once();
+
+ WorkflowJob p = jenkinsRule.jenkins.createProject(WorkflowJob.class, "p");
+ URL zipFile = getClass().getResource("tekton-test-project.zip");
+ assertThat(zipFile, is(notNullValue()));
+
+ p.setDefinition(new CpsFlowDefinition("pipeline { \n"
+ + " agent any\n"
+ + " stages {\n"
+ + " stage('Stage') {\n"
+ + " steps {\n"
+ + " unzip '" + zipFile.getPath() + "'\n"
+ + " tektonCreateRaw(inputType: 'FILE', input: '.tekton/task.yaml')\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + "}\n", true));
+
+ WorkflowRun b = jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());
+
+ assertThat(kubernetesRule.getMockServer().getRequestCount(), is(1));
+
+ String log = jenkinsRule.getLog(b);
+ System.out.println(log);
+
+ assertThat(log, containsString("Extracting: .tekton/task.yaml"));
+ assertThat(log, containsString("[Pipeline] tektonCreateRaw"));
+ assertThat(log, not(containsString(".tekton/task.yaml (No such file or directory)")));
+ }
+
+ @Test
+ public void testDeclarativePipelineWithYamlInput_Task() throws Exception {
+ TaskBuilder taskBuilder = new TaskBuilder()
+ .withNewMetadata()
+ .withName("testTask")
+ .endMetadata();
+
+ kubernetesRule.expect()
+ .post()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/test/tasks")
+ .andReturn(HttpURLConnection.HTTP_OK, taskBuilder.build()).once();
+
+ WorkflowJob p = jenkinsRule.jenkins.createProject(WorkflowJob.class, "p");
+ URL zipFile = getClass().getResource("tekton-test-project.zip");
+ assertThat(zipFile, is(notNullValue()));
+
+ p.setDefinition(new CpsFlowDefinition("pipeline { \n"
+ + " agent any\n"
+ + " stages {\n"
+ + " stage('Stage') {\n"
+ + " steps {\n"
+ + " unzip '" + zipFile.getPath() + "'\n"
+ + " tektonCreateRaw(inputType: 'YAML', input: \"\"\"apiVersion: tekton.dev/v1beta1\n"
+ + "kind: Task\n"
+ + "metadata:\n"
+ + " name: testTask\n"
+ + "\"\"\")\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + "}\n", true));
+
+ WorkflowRun b = jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());
+
+ assertThat(kubernetesRule.getMockServer().getRequestCount(), is(1));
+
+ String log = jenkinsRule.getLog(b);
+ System.out.println(log);
+
+ assertThat(log, containsString("Extracting: .tekton/task.yaml"));
+ assertThat(log, containsString("[Pipeline] tektonCreateRaw"));
+ assertThat(log, not(containsString(".tekton/task.yaml (No such file or directory)")));
+ }
+
+
+ @Test
+ public void testDeclarativePipelineWithYamlInput_PipelineRun() throws Exception {
+ ToolUtils.getJXPipelineBinary(ToolUtils.class.getClassLoader());
+
+ PipelineRunBuilder pipelineRunBuilder = new PipelineRunBuilder()
+ .withNewMetadata()
+ .withName("release")
+ .withNamespace("test")
+ .withUid("pipeline-run-uid")
+ .endMetadata()
+ .withNewSpec()
+ .withNewPipelineSpec()
+ .addNewTask()
+ .withName("pipelineTaskName")
+ .endTask()
+ .endPipelineSpec()
+ .endSpec()
+ .withNewStatus()
+ .withConditions(new Condition("lastTransitionTime","","","","True","Succeeded"))
+ .endStatus();
+
+ kubernetesRule.expect()
+ .post()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/test/pipelineruns")
+ .andReturn(HttpURLConnection.HTTP_OK, pipelineRunBuilder.build())
+ .once();
+
+ kubernetesRule.expect()
+ .get()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/test/pipelineruns/release")
+ .andReturn(HttpURLConnection.HTTP_OK, pipelineRunBuilder.build())
+ .once();
+
+ TaskRunList taskRunList = new TaskRunListBuilder()
+ .addToItems(
+ new TaskRunBuilder()
+ .withNewMetadata()
+ .withName("testTaskRun")
+ .withOwnerReferences(ownerReference("pipeline-run-uid"))
+ .endMetadata()
+ .build())
+ .build();
+
+ kubernetesRule.expect()
+ .get()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/test/taskruns?labelSelector=tekton.dev%2FpipelineTask%3DpipelineTaskName%2Ctekton.dev%2FpipelineRun%3Drelease")
+ .andReturn(HttpURLConnection.HTTP_OK, taskRunList)
+ .once();
+
+ Pod pod = new PodBuilder()
+ .withNewMetadata()
+ .withName("hello-world-pod")
+ .withNamespace("test")
+ .withOwnerReferences(ownerReference("TaskRun","testTaskRun"))
+ .endMetadata()
+ .withNewSpec()
+ .withContainers(
+ new ContainerBuilder()
+ .withName("hello-world-container")
+ .build()
+ )
+ .endSpec()
+ .withNewStatus()
+ .withPhase("Succeeded")
+ .withContainerStatuses(
+ new ContainerStatusBuilder()
+ .withName("hello-world-container")
+ .withState(
+ new ContainerStateBuilder()
+ .withTerminated(new ContainerStateTerminatedBuilder().withStartedAt("timestamp").build())
+ .build()
+ )
+ .build())
+ .endStatus()
+ .build();
+
+ PodList podList = new PodListBuilder()
+ .addToItems(pod)
+ .build();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/test/pods")
+ .andReturn(HttpURLConnection.HTTP_OK, podList).once();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/test/pods/hello-world-pod")
+ .andReturn(HttpURLConnection.HTTP_OK, pod).always();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/test/pods/hello-world-pod/log?pretty=false&container=hello-world-container&follow=true")
+ .andReturn(HttpURLConnection.HTTP_OK, "Whoop! This is the pod log").once();
+
+ WorkflowJob p = jenkinsRule.jenkins.createProject(WorkflowJob.class, "p");
+ URL zipFile = getClass().getResource("tekton-test-project.zip");
+ assertThat(zipFile, is(notNullValue()));
+
+ p.setDefinition(new CpsFlowDefinition("pipeline { \n"
+ + " agent any\n"
+ + " stages {\n"
+ + " stage('Stage') {\n"
+ + " steps {\n"
+ + " unzip '" + zipFile.getPath() + "'\n"
+ + " tektonCreateRaw(inputType: 'YAML', input: \"\"\"apiVersion: tekton.dev/v1beta1\n"
+ + "kind: PipelineRun\n"
+ + "metadata:\n"
+ + " name: release\n"
+ + "spec:\n"
+ + " params:\n"
+ + "\"\"\")\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + "}\n", true));
+
+ WorkflowRun b = jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());
+
+ String log = jenkinsRule.getLog(b);
+ System.out.println(log);
+
+ assertThat(log, containsString("[Pipeline] tektonCreateRaw"));
+ assertThat(log, containsString("[Tekton] Pod test/hello-world-pod"));
+ assertThat(log, containsString("[Tekton] Pod test/hello-world-pod - Running..."));
+ assertThat(log, containsString("[Tekton] Container test/hello-world-pod/hello-world-container"));
+ assertThat(log, containsString("[Tekton] Container test/hello-world-pod/hello-world-container - Completed"));
+ assertThat(log, containsString("Whoop! This is the pod log"));
+
+ assertThat(kubernetesRule.getMockServer().getRequestCount(), is(9));
+ }
+
+ @Test
+ public void testDeclarativePipelineWithYamlInput_PipelineRun_DifferentNamespace() throws Exception {
+ ToolUtils.getJXPipelineBinary(ToolUtils.class.getClassLoader());
+
+ PipelineRunBuilder pipelineRunBuilder = new PipelineRunBuilder()
+ .withNewMetadata()
+ .withName("release")
+ .withNamespace("tekton-pipelines")
+ .withUid("pipeline-run-uid")
+ .endMetadata()
+ .withNewSpec()
+ .withNewPipelineSpec()
+ .addNewTask()
+ .withName("pipelineTaskName")
+ .endTask()
+ .endPipelineSpec()
+ .endSpec()
+ .withNewStatus()
+ .withConditions(new Condition("lastTransitionTime","","","","True","Succeeded"))
+ .endStatus();
+
+ kubernetesRule.expect()
+ .post()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/tekton-pipelines/pipelineruns")
+ .andReturn(HttpURLConnection.HTTP_OK, pipelineRunBuilder.build())
+ .once();
+
+ kubernetesRule.expect()
+ .get()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/tekton-pipelines/pipelineruns/release")
+ .andReturn(HttpURLConnection.HTTP_OK, pipelineRunBuilder.build())
+ .once();
+
+ TaskRunList taskRunList = new TaskRunListBuilder()
+ .addToItems(
+ new TaskRunBuilder()
+ .withNewMetadata()
+ .withName("testTaskRun")
+ .withOwnerReferences(ownerReference("pipeline-run-uid"))
+ .endMetadata()
+ .build())
+ .build();
+
+ kubernetesRule.expect()
+ .get()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/tekton-pipelines/taskruns?labelSelector=tekton.dev%2FpipelineTask%3DpipelineTaskName%2Ctekton.dev%2FpipelineRun%3Drelease")
+ .andReturn(HttpURLConnection.HTTP_OK, taskRunList)
+ .once();
+
+ Pod pod = new PodBuilder()
+ .withNewMetadata()
+ .withName("hello-world-pod")
+ .withNamespace("tekton-pipelines")
+ .withOwnerReferences(ownerReference("TaskRun","testTaskRun"))
+ .endMetadata()
+ .withNewSpec()
+ .withContainers(
+ new ContainerBuilder()
+ .withName("hello-world-container")
+ .build()
+ )
+ .endSpec()
+ .withNewStatus()
+ .withPhase("Succeeded")
+ .withContainerStatuses(
+ new ContainerStatusBuilder()
+ .withName("hello-world-container")
+ .withState(
+ new ContainerStateBuilder()
+ .withTerminated(new ContainerStateTerminatedBuilder().withStartedAt("timestamp").build())
+ .build()
+ )
+ .build())
+ .endStatus()
+ .build();
+
+ PodList podList = new PodListBuilder()
+ .addToItems(pod)
+ .build();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/tekton-pipelines/pods")
+ .andReturn(HttpURLConnection.HTTP_OK, podList).once();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/tekton-pipelines/pods/hello-world-pod")
+ .andReturn(HttpURLConnection.HTTP_OK, pod).always();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/tekton-pipelines/pods/hello-world-pod/log?pretty=false&container=hello-world-container&follow=true")
+ .andReturn(HttpURLConnection.HTTP_OK, "Whoop! This is the pod log").once();
+
+ WorkflowJob p = jenkinsRule.jenkins.createProject(WorkflowJob.class, "p");
+ URL zipFile = getClass().getResource("tekton-test-project.zip");
+ assertThat(zipFile, is(notNullValue()));
+
+ p.setDefinition(new CpsFlowDefinition("pipeline { \n"
+ + " agent any\n"
+ + " stages {\n"
+ + " stage('Stage') {\n"
+ + " steps {\n"
+ + " unzip '" + zipFile.getPath() + "'\n"
+ + " tektonCreateRaw(inputType: 'YAML', input: \"\"\"apiVersion: tekton.dev/v1beta1\n"
+ + "kind: PipelineRun\n"
+ + "metadata:\n"
+ + " name: release\n"
+ + "spec:\n"
+ + " params:\n"
+ + "\"\"\", namespace: 'tekton-pipelines')\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + "}\n", true));
+
+ WorkflowRun b = jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());
+
+ String log = jenkinsRule.getLog(b);
+ System.out.println(log);
+
+ assertThat(log, containsString("[Pipeline] tektonCreateRaw"));
+ assertThat(log, containsString("[Tekton] Pod tekton-pipelines/hello-world-pod"));
+ assertThat(log, containsString("[Tekton] Pod tekton-pipelines/hello-world-pod - Running..."));
+ assertThat(log, containsString("[Tekton] Container tekton-pipelines/hello-world-pod/hello-world-container"));
+ assertThat(log, containsString("[Tekton] Container tekton-pipelines/hello-world-pod/hello-world-container - Completed"));
+ assertThat(log, containsString("Whoop! This is the pod log"));
+
+ assertThat(kubernetesRule.getMockServer().getRequestCount(), is(9));
+ }
+
+ @Test
+ public void testDeclarativePipelineWithYamlInput_PipelineRun_FailingContainer() throws Exception {
+ ToolUtils.getJXPipelineBinary(ToolUtils.class.getClassLoader());
+
+ PipelineRunBuilder pipelineRunBuilder = new PipelineRunBuilder()
+ .withNewMetadata()
+ .withName("release")
+ .withNamespace("tekton-pipelines")
+ .withUid("pipeline-run-uid")
+ .endMetadata()
+ .withNewSpec()
+ .withNewPipelineSpec()
+ .addNewTask()
+ .withName("pipelineTaskName")
+ .endTask()
+ .endPipelineSpec()
+ .endSpec()
+ .withNewStatus()
+ .withConditions(new Condition("lastTransitionTime","","","","True","Succeeded"))
+ .endStatus();
+
+ kubernetesRule.expect()
+ .post()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/tekton-pipelines/pipelineruns")
+ .andReturn(HttpURLConnection.HTTP_OK, pipelineRunBuilder.build())
+ .once();
+
+ kubernetesRule.expect()
+ .get()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/tekton-pipelines/pipelineruns/release")
+ .andReturn(HttpURLConnection.HTTP_OK, pipelineRunBuilder.build())
+ .once();
+
+ TaskRunList taskRunList = new TaskRunListBuilder()
+ .addToItems(
+ new TaskRunBuilder()
+ .withNewMetadata()
+ .withName("testTaskRun")
+ .withOwnerReferences(ownerReference("pipeline-run-uid"))
+ .endMetadata()
+ .build())
+ .build();
+
+ kubernetesRule.expect()
+ .get()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/tekton-pipelines/taskruns?labelSelector=tekton.dev%2FpipelineTask%3DpipelineTaskName%2Ctekton.dev%2FpipelineRun%3Drelease")
+ .andReturn(HttpURLConnection.HTTP_OK, taskRunList)
+ .once();
+
+ Pod pod = new PodBuilder()
+ .withNewMetadata()
+ .withName("hello-world-pod")
+ .withNamespace("tekton-pipelines")
+ .withOwnerReferences(ownerReference("TaskRun","testTaskRun"))
+ .endMetadata()
+ .withNewSpec()
+ .withContainers(
+ new ContainerBuilder()
+ .withName("hello-world-container")
+ .build()
+ )
+ .endSpec()
+ .withNewStatus()
+ .withPhase("Failed")
+ .withContainerStatuses(
+ new ContainerStatusBuilder()
+ .withName("hello-world-container")
+ .withState(
+ new ContainerStateBuilder()
+ .withTerminated(
+ new ContainerStateTerminatedBuilder()
+ .withStartedAt("timestamp")
+ .withMessage("Failure Message")
+ .withReason("Error")
+ .withExitCode(1)
+ .build())
+ .build()
+ )
+ .build())
+ .endStatus()
+ .build();
+
+ PodList podList = new PodListBuilder()
+ .addToItems(pod)
+ .build();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/tekton-pipelines/pods")
+ .andReturn(HttpURLConnection.HTTP_OK, podList).once();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/tekton-pipelines/pods/hello-world-pod")
+ .andReturn(HttpURLConnection.HTTP_OK, pod).always();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/tekton-pipelines/pods/hello-world-pod/log?pretty=false&container=hello-world-container&follow=true")
+ .andReturn(HttpURLConnection.HTTP_OK, "Whoop! This is the pod log").once();
+
+ WorkflowJob p = jenkinsRule.jenkins.createProject(WorkflowJob.class, "p");
+ URL zipFile = getClass().getResource("tekton-test-project.zip");
+ assertThat(zipFile, is(notNullValue()));
+
+ p.setDefinition(new CpsFlowDefinition("pipeline { \n"
+ + " agent any\n"
+ + " stages {\n"
+ + " stage('Stage') {\n"
+ + " steps {\n"
+ + " unzip '" + zipFile.getPath() + "'\n"
+ + " tektonCreateRaw(inputType: 'YAML', input: \"\"\"apiVersion: tekton.dev/v1beta1\n"
+ + "kind: PipelineRun\n"
+ + "metadata:\n"
+ + " name: release\n"
+ + "spec:\n"
+ + " params:\n"
+ + "\"\"\", namespace: 'tekton-pipelines')\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + "}\n", true));
+
+ WorkflowRun b = jenkinsRule.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get());
+
+ String log = jenkinsRule.getLog(b);
+ System.out.println(log);
+
+ assertThat(log, containsString("[Pipeline] tektonCreateRaw"));
+ assertThat(log, containsString("[Tekton] Pod tekton-pipelines/hello-world-pod"));
+ assertThat(log, containsString("[Tekton] Pod tekton-pipelines/hello-world-pod - Running..."));
+ assertThat(log, containsString("[Tekton] Container tekton-pipelines/hello-world-pod/hello-world-container"));
+ assertThat(log, containsString("[Tekton] Container tekton-pipelines/hello-world-pod/hello-world-container - Error"));
+ assertThat(log, containsString("[Tekton] Pod tekton-pipelines/hello-world-pod Status: Failed"));
+ assertThat(log, containsString("Whoop! This is the pod log"));
+
+ assertThat(kubernetesRule.getMockServer().getRequestCount(), is(8));
+ }
+
+ @Test
+ public void testDeclarativePipelineWithYamlInput_PipelineRun_FailingPipelineRun() throws Exception {
+ ToolUtils.getJXPipelineBinary(ToolUtils.class.getClassLoader());
+
+ PipelineRunBuilder pipelineRunBuilder = new PipelineRunBuilder()
+ .withNewMetadata()
+ .withName("release")
+ .withNamespace("tekton-pipelines")
+ .withUid("pipeline-run-uid")
+ .endMetadata()
+ .withNewSpec()
+ .withNewPipelineSpec()
+ .addNewTask()
+ .withName("pipelineTaskName")
+ .endTask()
+ .endPipelineSpec()
+ .endSpec()
+ .withNewStatus()
+ .withConditions(new Condition("lastTransitionTime","Failure Message","Failure Reason","","False","Succeeded"))
+ .endStatus();
+
+ kubernetesRule.expect()
+ .post()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/tekton-pipelines/pipelineruns")
+ .andReturn(HttpURLConnection.HTTP_OK, pipelineRunBuilder.build())
+ .once();
+
+ kubernetesRule.expect()
+ .get()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/tekton-pipelines/pipelineruns/release")
+ .andReturn(HttpURLConnection.HTTP_OK, pipelineRunBuilder.build())
+ .once();
+
+ TaskRunList taskRunList = new TaskRunListBuilder()
+ .addToItems(
+ new TaskRunBuilder()
+ .withNewMetadata()
+ .withName("testTaskRun")
+ .withOwnerReferences(ownerReference("pipeline-run-uid"))
+ .endMetadata()
+ .build())
+ .build();
+
+ kubernetesRule.expect()
+ .get()
+ .withPath("/apis/tekton.dev/v1beta1/namespaces/tekton-pipelines/taskruns?labelSelector=tekton.dev%2FpipelineTask%3DpipelineTaskName%2Ctekton.dev%2FpipelineRun%3Drelease")
+ .andReturn(HttpURLConnection.HTTP_OK, taskRunList)
+ .once();
+
+ Pod pod = new PodBuilder()
+ .withNewMetadata()
+ .withName("hello-world-pod")
+ .withNamespace("tekton-pipelines")
+ .withOwnerReferences(ownerReference("TaskRun","testTaskRun"))
+ .endMetadata()
+ .withNewSpec()
+ .withContainers(
+ new ContainerBuilder()
+ .withName("hello-world-container")
+ .build()
+ )
+ .endSpec()
+ .withNewStatus()
+ .withPhase("Succeeded")
+ .withContainerStatuses(
+ new ContainerStatusBuilder()
+ .withName("hello-world-container")
+ .withState(
+ new ContainerStateBuilder()
+ .withTerminated(new ContainerStateTerminatedBuilder().withStartedAt("timestamp").build())
+ .build()
+ )
+ .build())
+ .endStatus()
+ .build();
+
+ PodList podList = new PodListBuilder()
+ .addToItems(pod)
+ .build();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/tekton-pipelines/pods")
+ .andReturn(HttpURLConnection.HTTP_OK, podList).once();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/tekton-pipelines/pods/hello-world-pod")
+ .andReturn(HttpURLConnection.HTTP_OK, pod).always();
+
+ kubernetesRule.expect().get().withPath("/api/v1/namespaces/tekton-pipelines/pods/hello-world-pod/log?pretty=false&container=hello-world-container&follow=true")
+ .andReturn(HttpURLConnection.HTTP_OK, "Whoop! This is the pod log").once();
+
+ WorkflowJob p = jenkinsRule.jenkins.createProject(WorkflowJob.class, "p");
+ URL zipFile = getClass().getResource("tekton-test-project.zip");
+ assertThat(zipFile, is(notNullValue()));
+
+ p.setDefinition(new CpsFlowDefinition("pipeline { \n"
+ + " agent any\n"
+ + " stages {\n"
+ + " stage('Stage') {\n"
+ + " steps {\n"
+ + " unzip '" + zipFile.getPath() + "'\n"
+ + " tektonCreateRaw(inputType: 'YAML', input: \"\"\"apiVersion: tekton.dev/v1beta1\n"
+ + "kind: PipelineRun\n"
+ + "metadata:\n"
+ + " name: release\n"
+ + "spec:\n"
+ + " params:\n"
+ + "\"\"\", namespace: 'tekton-pipelines')\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + "}\n", true));
+
+ WorkflowRun b = jenkinsRule.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get());
+
+ String log = jenkinsRule.getLog(b);
+ System.out.println(log);
+
+ assertThat(log, containsString("[Pipeline] tektonCreateRaw"));
+ assertThat(log, containsString("[Tekton] Pod tekton-pipelines/hello-world-pod"));
+ assertThat(log, containsString("[Tekton] Pod tekton-pipelines/hello-world-pod - Running..."));
+ assertThat(log, containsString("[Tekton] Container tekton-pipelines/hello-world-pod/hello-world-container"));
+ assertThat(log, containsString("[Tekton] Container tekton-pipelines/hello-world-pod/hello-world-container - Completed"));
+ assertThat(log, containsString("Whoop! This is the pod log"));
+
+ assertThat(kubernetesRule.getMockServer().getRequestCount(), is(9));
+ }
+
+ private String contents(String filename) throws IOException {
+ return IOUtils.toString(this.getClass().getResourceAsStream(filename), StandardCharsets.UTF_8.name());
+ }
+
+ private OwnerReference ownerReference(String uid) {
+ return new OwnerReference("", false, false, "", "", uid);
+ }
+
+ private OwnerReference ownerReference(String kind, String name) {
+ return new OwnerReference("", false, false, kind, name, "");
+ }
+}