/*
This file is part of Delivery Pipeline Plugin.
Delivery Pipeline Plugin is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Delivery Pipeline Plugin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Delivery Pipeline Plugin.
If not, see <http://www.gnu.org/licenses/>.
*/
package se.diabol.jenkins.pipeline.domain.task;
import au.com.centrumsystems.hudson.plugin.buildpipeline.trigger.BuildPipelineTrigger;
import hudson.Launcher;
import hudson.matrix.Axis;
import hudson.matrix.AxisList;
import hudson.matrix.MatrixConfiguration;
import hudson.matrix.MatrixProject;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Result;
import hudson.model.User;
import hudson.security.ACL;
import hudson.security.GlobalMatrixAuthorizationStrategy;
import hudson.security.Permission;
import hudson.tasks.BuildTrigger;
import hudson.util.OneShotEvent;
import jenkins.model.Jenkins;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.FailureBuilder;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestBuilder;
import org.jvnet.hudson.test.UnstableBuilder;
import se.diabol.jenkins.pipeline.DeliveryPipelineView;
import se.diabol.jenkins.pipeline.PipelineProperty;
import java.io.IOException;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class TaskTest {
@Rule
public JenkinsRule jenkins = new JenkinsRule();
@Test
public void testGetAg() throws Exception {
FreeStyleProject project = jenkins.createFreeStyleProject("test");
jenkins.getInstance().setQuietPeriod(0);
Task task = Task.getPrototypeTask(project, true);
assertNotNull(task);
assertFalse(task.isManual());
assertFalse(task.isRebuildable());
Task aggregatedTask = task.getAggregatedTask(null, Jenkins.getInstance());
assertNotNull(aggregatedTask);
assertNotNull(task.getLink());
assertEquals(task.getLink(), aggregatedTask.getLink());
FreeStyleBuild build = jenkins.buildAndAssertSuccess(project);
aggregatedTask = task.getAggregatedTask(build, Jenkins.getInstance());
assertNotNull(aggregatedTask);
assertEquals("job/test/1/", aggregatedTask.getLink());
}
@Test
public void testManualTask() throws Exception {
FreeStyleProject a = jenkins.createFreeStyleProject("a");
FreeStyleProject b = jenkins.createFreeStyleProject("b");
a.getPublishersList().add(new BuildPipelineTrigger("b", null));
jenkins.getInstance().rebuildDependencyGraph();
Task task = Task.getPrototypeTask(b, false);
assertTrue(task.isManual());
}
@Test
public void testGetLatestRunning() throws Exception {
final String mockDescription = "some description";
final OneShotEvent buildStarted = new OneShotEvent();
final OneShotEvent buildBuilding = new OneShotEvent();
FreeStyleProject project = jenkins.createFreeStyleProject("test");
project.getBuildersList().add(new TestBuilder() {
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
BuildListener listener) throws InterruptedException, IOException {
buildStarted.signal();
buildBuilding.block();
return true;
}
});
Task prototype = Task.getPrototypeTask(project, true);
project.scheduleBuild2(0);
buildStarted.block(); // wait for the build to really start
project.getLastBuild().setDescription(mockDescription);
Task latest = prototype.getLatestTask(jenkins.getInstance(), project.getLastBuild());
Task aggregated = prototype.getAggregatedTask(project.getLastBuild(), jenkins.getInstance());
assertEquals("job/test/1/console", latest.getLink());
assertTrue(latest.getStatus().isRunning());
assertEquals(mockDescription, aggregated.getDescription());
assertEquals("job/test/1/console", aggregated.getLink());
assertTrue(aggregated.getStatus().isRunning());
buildBuilding.signal();
jenkins.waitUntilNoActivity();
}
@Test
@Issue("JENKINS-22654")
public void testTaskNameForMultiConfiguration() throws Exception {
MatrixProject project = jenkins.createMatrixProject("Multi");
project.setAxes(new AxisList(new Axis("axis", "foo", "bar")));
project.addProperty(new PipelineProperty("task", "stage", ""));
Collection<MatrixConfiguration> configurations = project.getActiveConfigurations();
for (MatrixConfiguration configuration : configurations) {
Task task = Task.getPrototypeTask(configuration, true);
assertEquals("task " + configuration.getName(), task.getName());
}
}
@Test
public void testFailedThenQueued() throws Exception {
FreeStyleProject a = jenkins.createFreeStyleProject("a");
FreeStyleProject b = jenkins.createFreeStyleProject("b");
jenkins.setQuietPeriod(0);
a.getPublishersList().add(new BuildPipelineTrigger("b", null));
b.getBuildersList().add(new FailureBuilder());
FreeStyleBuild build = jenkins.buildAndAssertSuccess(a);
Task task = Task.getPrototypeTask(b, false);
assertTrue(task.getLatestTask(jenkins.getInstance(), build).getStatus().isIdle());
DeliveryPipelineView view = new DeliveryPipelineView("Pipeline", jenkins.getInstance());
view.triggerManual("b", "a", "1");
jenkins.waitUntilNoActivity();
assertTrue(task.getLatestTask(jenkins.getInstance(), build).getStatus().isFailed());
jenkins.getInstance().setNumExecutors(0);
jenkins.getInstance().reload();
view.triggerManual("b", "a", "1");
assertTrue(task.getLatestTask(jenkins.getInstance(), build).getStatus().isQueued());
}
@Test
public void testIsRebuildable() throws Exception {
jenkins.setQuietPeriod(0);
FreeStyleProject project = jenkins.createFreeStyleProject("project");
Task task = Task.getPrototypeTask(project, false);
//IDLE
assertFalse(task.getLatestTask(jenkins.getInstance(), null).isRebuildable());
//FAILED
project.getBuildersList().add(new FailureBuilder());
project.scheduleBuild2(0);
jenkins.waitUntilNoActivity();
assertTrue(task.getLatestTask(jenkins.getInstance(), project.getLastBuild()).isRebuildable());
//UNSTABLE
project.getBuildersList().clear();
project.getBuildersList().add(new UnstableBuilder());
project.scheduleBuild2(0);
jenkins.waitUntilNoActivity();
assertTrue(task.getLatestTask(jenkins.getInstance(), project.getLastBuild()).isRebuildable());
}
@Test
@Issue("JENKINS-28845")
public void testIsRebuildableNoPermission() throws Exception {
FreeStyleProject a = jenkins.createFreeStyleProject("A");
FreeStyleProject b = jenkins.createFreeStyleProject("B");
b.getBuildersList().add(new FailureBuilder());
a.getPublishersList().add(new BuildTrigger("B", false));
jenkins.setQuietPeriod(0);
jenkins.getInstance().rebuildDependencyGraph();
FreeStyleBuild firstBuild = jenkins.buildAndAssertSuccess(a);
jenkins.waitUntilNoActivity();
assertNotNull(b.getLastBuild());
assertTrue(b.getLastBuild().getResult().equals(Result.FAILURE));
jenkins.getInstance().setSecurityRealm(jenkins.createDummySecurityRealm());
GlobalMatrixAuthorizationStrategy gmas = new GlobalMatrixAuthorizationStrategy();
gmas.add(Permission.READ, "devel");
jenkins.getInstance().setAuthorizationStrategy(gmas);
SecurityContext oldContext = ACL.impersonate(User.get("devel").impersonate());
Task prototype = Task.getPrototypeTask(b, false);
Task task = prototype.getLatestTask(jenkins.getInstance(), firstBuild);
assertNotNull(task);
assertFalse(task.isRebuildable());
SecurityContextHolder.setContext(oldContext);
}
@Test
@Issue("JENKINS-30170")
public void testTaskName() throws Exception {
testSimplePipelineTaskNames("Build", "Deploy", "Build", "Deploy", "Build", "Deploy");
}
@Test
public void testTaskNameMacro() throws Exception {
testSimplePipelineTaskNames("Build ${BUILD_NUMBER}", "Deploy ${BUILD_NUMBER}", "Build ...",
"Deploy ...", "Build 1", "Deploy 1");
}
@Test
public void testTaskNameMacroOnly() throws Exception {
testSimplePipelineTaskNames("${BUILD_NUMBER}", "${BUILD_NUMBER}", "...",
"...", "1", "1");
}
private void testSimplePipelineTaskNames(String taskNameA, String taskNameB, String expectedBeforeA,
String expectedBeforeB, String expectedAfterA, String expectedAfterB)
throws Exception {
FreeStyleProject a = jenkins.createFreeStyleProject("A");
FreeStyleProject b = jenkins.createFreeStyleProject("B");
a.addProperty(new PipelineProperty(taskNameA, "Stage Build", null));
b.addProperty(new PipelineProperty(taskNameB, "Stage Deploy", null));
a.getPublishersList().add(new BuildTrigger("B", false));
jenkins.setQuietPeriod(0);
jenkins.getInstance().rebuildDependencyGraph();
Task taskA = Task.getPrototypeTask(a, true).getLatestTask(jenkins.getInstance(), null);
Task taskB = Task.getPrototypeTask(b, false).getLatestTask(jenkins.getInstance(), null);
assertEquals(expectedBeforeA, taskA.getName());
assertEquals(expectedBeforeB, taskB.getName());
FreeStyleBuild firstBuild = jenkins.buildAndAssertSuccess(a);
jenkins.waitUntilNoActivity();
taskA = Task.getPrototypeTask(a, true).getLatestTask(jenkins.getInstance(), firstBuild);
taskB = Task.getPrototypeTask(b, false).getLatestTask(jenkins.getInstance(), firstBuild);
assertEquals(expectedAfterA, taskA.getName());
assertEquals(expectedAfterB, taskB.getName());
}
}