|
2 | 2 |
|
3 | 3 | import hudson.model.FreeStyleBuild;
|
4 | 4 | import hudson.model.FreeStyleProject;
|
| 5 | +import hudson.model.Label; |
5 | 6 | import hudson.model.Queue;
|
6 | 7 | import hudson.model.Result;
|
| 8 | +import hudson.model.Run; |
7 | 9 | import java.util.Arrays;
|
| 10 | +import java.util.List; |
| 11 | +import java.util.Objects; |
| 12 | +import java.util.concurrent.TimeUnit; |
8 | 13 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
|
9 | 14 | import org.jenkinsci.plugins.workflow.cps.CpsFlowExecution;
|
10 | 15 | import org.jenkinsci.plugins.workflow.job.WorkflowJob;
|
11 | 16 | import org.jenkinsci.plugins.workflow.job.WorkflowRun;
|
12 |
| -import org.junit.Assert; |
| 17 | +import org.jenkinsci.plugins.workflow.support.steps.build.DownstreamBuildAction.DownstreamBuild; |
13 | 18 | import org.junit.ClassRule;
|
14 | 19 | import org.junit.Rule;
|
15 | 20 | import org.junit.Test;
|
16 | 21 | import org.jvnet.hudson.test.BuildWatcher;
|
17 | 22 | import org.jvnet.hudson.test.JenkinsRule;
|
18 | 23 | import org.jvnet.hudson.test.JenkinsSessionRule;
|
| 24 | +import static org.awaitility.Awaitility.await; |
| 25 | +import static org.hamcrest.MatcherAssert.assertThat; |
| 26 | +import static org.hamcrest.Matchers.equalTo; |
| 27 | +import static org.hamcrest.Matchers.notNullValue; |
| 28 | +import static org.hamcrest.Matchers.nullValue; |
| 29 | +import static org.junit.Assert.assertEquals; |
| 30 | +import static org.junit.Assert.assertNotNull; |
19 | 31 |
|
20 | 32 | /**
|
21 | 33 | * @author Vivek Pandey
|
22 | 34 | */
|
23 |
| -public class BuildTriggerStepRestartTest extends Assert { |
| 35 | +public class BuildTriggerStepRestartTest { |
24 | 36 |
|
25 | 37 | @ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
|
26 | 38 | @Rule public JenkinsSessionRule sessions = new JenkinsSessionRule();
|
@@ -64,6 +76,79 @@ public void restartBetweenJobs() throws Throwable {
|
64 | 76 | sessions.then(j -> j.jenkins.getItemByFullName("test1", FreeStyleProject.class).getBuildByNumber(1).delete());
|
65 | 77 | }
|
66 | 78 |
|
| 79 | + @Test |
| 80 | + public void downstreamBuildActionUpstreamCompletesBeforeDownstreamStarts() throws Throwable { |
| 81 | + sessions.then(j -> { |
| 82 | + FreeStyleProject downstream = j.createFreeStyleProject("downstream"); |
| 83 | + downstream.setAssignedLabel(Label.parseExpression("agent")); |
| 84 | + WorkflowJob upstream = j.jenkins.createProject(WorkflowJob.class, "upstream"); |
| 85 | + upstream.setDefinition(new CpsFlowDefinition("build job: 'downstream', wait: false", true)); |
| 86 | + WorkflowRun upstreamRun = j.buildAndAssertSuccess(upstream); |
| 87 | + // Check action while the build is still in the queue. |
| 88 | + String buildStepId = BuildTriggerStepTest.findFirstNodeWithDescriptor(upstreamRun.getExecution(), BuildTriggerStep.DescriptorImpl.class).getId(); |
| 89 | + var downstreamBuildAction = upstreamRun.getAction(DownstreamBuildAction.class); |
| 90 | + var downstreamBuild = downstreamBuildAction.getDownstreamBuilds().get(0); |
| 91 | + assertThat(downstreamBuild.getFlowNodeId(), equalTo(buildStepId)); |
| 92 | + assertThat(downstreamBuild.getJobFullName(), equalTo(downstream.getFullName())); |
| 93 | + assertThat(downstreamBuild.getBuildNumber(), nullValue()); |
| 94 | + assertThat(downstreamBuild.getBuild(), nullValue()); |
| 95 | + // Check again once the build has started. |
| 96 | + j.createOnlineSlave(Label.parseExpression("agent")); |
| 97 | + await().atMost(10, TimeUnit.SECONDS).until(() -> downstreamBuild.getBuildNumber(), notNullValue()); |
| 98 | + Run<?, ?> downstreamRun = downstream.getLastBuild(); |
| 99 | + assertThat(downstreamBuild.getJobFullName(), equalTo(downstream.getFullName())); |
| 100 | + assertThat(downstreamBuild.getBuildNumber(), equalTo(downstreamRun.getNumber())); |
| 101 | + assertThat(downstreamBuild.getBuild(), equalTo(downstreamRun)); |
| 102 | + j.waitForCompletion(downstreamRun); |
| 103 | + }); |
| 104 | + sessions.then(j -> { |
| 105 | + FreeStyleProject downstream = j.jenkins.getItemByFullName("downstream", FreeStyleProject.class); |
| 106 | + WorkflowJob upstream = j.jenkins.getItemByFullName("upstream", WorkflowJob.class); |
| 107 | + WorkflowRun upstreamRun = upstream.getLastBuild(); |
| 108 | + String buildStepId = BuildTriggerStepTest.findFirstNodeWithDescriptor(upstreamRun.getExecution(), BuildTriggerStep.DescriptorImpl.class).getId(); |
| 109 | + var downstreamBuildAction = upstreamRun.getAction(DownstreamBuildAction.class); |
| 110 | + var downstreamBuild = downstreamBuildAction.getDownstreamBuilds().get(0); |
| 111 | + assertThat(downstreamBuild.getFlowNodeId(), equalTo(buildStepId)); |
| 112 | + assertThat(downstreamBuild.getJobFullName(), equalTo(downstream.getFullName())); |
| 113 | + assertThat(downstreamBuild.getBuildNumber(), equalTo(downstream.getLastBuild().getNumber())); |
| 114 | + assertThat(downstreamBuild.getBuild(), equalTo(downstream.getLastBuild())); |
| 115 | + }); |
| 116 | + } |
| 117 | + |
| 118 | + @Test |
| 119 | + public void downstreamBuildActionMultipleBuilds() throws Throwable { |
| 120 | + sessions.then(j -> { |
| 121 | + FreeStyleProject downstream = j.createFreeStyleProject("downstream"); |
| 122 | + WorkflowJob upstream = j.jenkins.createProject(WorkflowJob.class, "upstream"); |
| 123 | + upstream.setDefinition(new CpsFlowDefinition("build 'downstream'; build 'downstream'", true)); |
| 124 | + WorkflowRun upstreamRun = j.buildAndAssertSuccess(upstream); |
| 125 | + List<DownstreamBuild> downstreamBuilds = upstreamRun.getAction(DownstreamBuildAction.class).getDownstreamBuilds(); |
| 126 | + await().atMost(10, TimeUnit.SECONDS).until( |
| 127 | + () -> downstreamBuilds.stream().map(DownstreamBuild::getBuildNumber).filter(Objects::nonNull).count(), |
| 128 | + equalTo(2L)); |
| 129 | + for (Run<?, ?> downstreamRun : downstream.getBuilds()) { |
| 130 | + String nodeId = downstreamRun.getCause(BuildUpstreamCause.class).getNodeId(); |
| 131 | + var downstreamBuild = downstreamBuilds.stream().filter(db -> db.getFlowNodeId().equals(nodeId)).findFirst().get(); |
| 132 | + assertThat(downstreamBuild.getJobFullName(), equalTo(downstream.getFullName())); |
| 133 | + assertThat(downstreamBuild.getBuildNumber(), equalTo(downstreamRun.getNumber())); |
| 134 | + assertThat(downstreamBuild.getBuild(), equalTo(downstreamRun)); |
| 135 | + } |
| 136 | + }); |
| 137 | + sessions.then(j -> { |
| 138 | + FreeStyleProject downstream = j.jenkins.getItemByFullName("downstream", FreeStyleProject.class); |
| 139 | + WorkflowJob upstream = j.jenkins.getItemByFullName("upstream", WorkflowJob.class); |
| 140 | + WorkflowRun upstreamRun = upstream.getLastBuild(); |
| 141 | + List<DownstreamBuild> downstreamBuilds = upstreamRun.getAction(DownstreamBuildAction.class).getDownstreamBuilds(); |
| 142 | + for (Run<?, ?> downstreamRun : downstream.getBuilds()) { |
| 143 | + String nodeId = downstreamRun.getCause(BuildUpstreamCause.class).getNodeId(); |
| 144 | + var downstreamBuild = downstreamBuilds.stream().filter(db -> db.getFlowNodeId().equals(nodeId)).findFirst().get(); |
| 145 | + assertThat(downstreamBuild.getJobFullName(), equalTo(downstream.getFullName())); |
| 146 | + assertThat(downstreamBuild.getBuildNumber(), equalTo(downstreamRun.getNumber())); |
| 147 | + assertThat(downstreamBuild.getBuild(), equalTo(downstreamRun)); |
| 148 | + } |
| 149 | + }); |
| 150 | + } |
| 151 | + |
67 | 152 | private static void assertFreeStyleProjectsInQueue(int count, JenkinsRule j) {
|
68 | 153 | Queue.Item[] items = j.jenkins.getQueue().getItems();
|
69 | 154 | int actual = 0;
|
|
0 commit comments