/* 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; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import au.com.centrumsystems.hudson.plugin.buildpipeline.BuildPipelineView; import au.com.centrumsystems.hudson.plugin.buildpipeline.DownstreamProjectGridBuilder; import au.com.centrumsystems.hudson.plugin.buildpipeline.trigger.BuildPipelineTrigger; import hudson.model.Cause; import hudson.model.Descriptor; import hudson.model.FreeStyleProject; import hudson.model.ItemGroup; import hudson.model.Saveable; import hudson.plugins.parameterizedtrigger.AbstractBuildParameterFactory; import hudson.plugins.parameterizedtrigger.BlockableBuildTriggerConfig; import hudson.plugins.parameterizedtrigger.BlockingBehaviour; import hudson.plugins.parameterizedtrigger.BuildTriggerConfig; import hudson.plugins.parameterizedtrigger.ResultCondition; import hudson.plugins.parameterizedtrigger.TriggerBuilder; import hudson.tasks.BuildTrigger; import hudson.tasks.Publisher; import hudson.util.DescribableList; import jenkins.model.Jenkins; import join.JoinTrigger; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockFolder; import org.kohsuke.stapler.StaplerRequest; import org.mockito.Mockito; import se.diabol.jenkins.pipeline.PipelineProperty; import se.diabol.jenkins.pipeline.domain.status.Status; import se.diabol.jenkins.pipeline.domain.task.Task; import se.diabol.jenkins.pipeline.util.BuildUtil; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class PipelineTest { @Rule public JenkinsRule jenkins = new JenkinsRule(); private static final boolean PAGING_DISABLED = false; private static final boolean SHOW_CHANGES = true; @Test public void testExtractPipelineEmptyPropertyAndNullProperty() throws Exception { FreeStyleProject job = jenkins.createFreeStyleProject("job"); Pipeline pipeline = Pipeline.extractPipeline("Pipeline", job); assertEquals(1, pipeline.getStages().size()); assertEquals("job", pipeline.getStages().get(0).getName()); assertEquals("job", pipeline.getStages().get(0).getTasks().get(0).getName()); job.addProperty(new PipelineProperty("", "", "")); pipeline = Pipeline.extractPipeline("Pipeline", job); assertEquals(1, pipeline.getStages().size()); assertEquals("job", pipeline.getStages().get(0).getName()); assertEquals("job", pipeline.getStages().get(0).getTasks().get(0).getName()); } @Test public void testExtractPipeline() throws Exception { final FreeStyleProject compile = jenkins.createFreeStyleProject("comp"); final FreeStyleProject deploy = jenkins.createFreeStyleProject("deploy"); final FreeStyleProject test = jenkins.createFreeStyleProject("test"); compile.addProperty(new PipelineProperty("Compile", "Build", "")); compile.save(); deploy.addProperty(new PipelineProperty("Deploy", "Deploy", "")); deploy.save(); test.addProperty(new PipelineProperty("Test", "Test", "")); test.save(); compile.getPublishersList().add(new BuildTrigger("test", false)); test.getPublishersList().add(new BuildTrigger("deploy", false)); jenkins.getInstance().rebuildDependencyGraph(); Pipeline pipeline = Pipeline.extractPipeline("Piper", compile); assertNotNull(pipeline); assertEquals("Piper", pipeline.getName()); assertEquals(3, pipeline.getStages().size()); Stage buildStage = pipeline.getStages().get(0); assertEquals("Build", buildStage.getName()); assertEquals(1, buildStage.getTasks().size()); assertEquals("Compile", buildStage.getTasks().get(0).getName()); assertEquals("comp", buildStage.getTasks().get(0).getId()); Stage testStage = pipeline.getStages().get(1); assertEquals("Test", testStage.getName()); assertEquals(1, testStage.getTasks().size()); assertEquals("Test", testStage.getTasks().get(0).getName()); assertEquals("test", testStage.getTasks().get(0).getId()); Stage deployStage = pipeline.getStages().get(2); assertEquals("Deploy", deployStage.getName()); assertEquals(1, deployStage.getTasks().size()); assertEquals("Deploy", deployStage.getTasks().get(0).getName()); assertEquals("deploy", deployStage.getTasks().get(0).getId()); } @Test public void testExtractSimpleForkJoinPipeline() throws Exception { FreeStyleProject build = jenkins.createFreeStyleProject("build"); build.addProperty(new PipelineProperty(null, "build", "")); FreeStyleProject deploy1 = jenkins.createFreeStyleProject("deploy1"); deploy1.addProperty(new PipelineProperty(null, "CI", "")); FreeStyleProject deploy2 = jenkins.createFreeStyleProject("deploy2"); deploy2.addProperty(new PipelineProperty(null, "CI", "")); FreeStyleProject deploy3 = jenkins.createFreeStyleProject("deploy3"); deploy3.addProperty(new PipelineProperty(null, "QA", "")); build.getPublishersList().add(new BuildTrigger("deploy1,deploy2", false)); deploy1.getPublishersList().add(new BuildTrigger("deploy3", false)); deploy2.getPublishersList().add(new BuildTrigger("deploy3", false)); jenkins.getInstance().rebuildDependencyGraph(); Pipeline pipeline = Pipeline.extractPipeline("Pipeline", build); assertEquals(3, pipeline.getStages().size()); assertEquals(1, pipeline.getStages().get(2).getTasks().size()); assertEquals("deploy3", pipeline.getStages().get(2).getTasks().get(0).getName()); } @Test public void testExtractPipelineWithSubProjects() throws Exception { FreeStyleProject build = jenkins.createFreeStyleProject("build"); build.addProperty(new PipelineProperty("Build", "Build", "")); FreeStyleProject sonar = jenkins.createFreeStyleProject("sonar"); sonar.addProperty(new PipelineProperty("Sonar", "Build", "")); FreeStyleProject deploy = jenkins.createFreeStyleProject("deploy"); deploy.addProperty(new PipelineProperty("Deploy", "QA", "")); build.getBuildersList().add( new TriggerBuilder( new BlockableBuildTriggerConfig("sonar", new BlockingBehaviour("never", "never", "never"), null))); build.getPublishersList().add(new BuildTrigger("deploy", false)); jenkins.getInstance().rebuildDependencyGraph(); Pipeline pipeline = Pipeline.extractPipeline("Pipeline", build); assertEquals(2, pipeline.getStages().size()); assertEquals(2, pipeline.getStages().get(0).getTasks().size()); assertEquals(1, pipeline.getStages().get(1).getTasks().size()); } @Test public void testCreatePipelineAggregatedSharedTask() throws Exception { final FreeStyleProject build1 = jenkins.createFreeStyleProject("build1"); final FreeStyleProject build2 = jenkins.createFreeStyleProject("build2"); final FreeStyleProject sonar = jenkins.createFreeStyleProject("sonar1"); final FreeStyleProject test = jenkins.createFreeStyleProject("test"); jenkins.createFreeStyleProject("prod"); build1.getPublishersList().add(new BuildTrigger("sonar1,test", true)); build2.getPublishersList().add(new BuildTrigger("sonar1", true)); test.getPublishersList().add(new BuildPipelineTrigger("prod", null)); jenkins.getInstance().rebuildDependencyGraph(); jenkins.setQuietPeriod(0); final Pipeline pipe1 = Pipeline.extractPipeline("pipe1", build1); final Pipeline pipe2 = Pipeline.extractPipeline("pipe2", build2); Pipeline aggregated1 = pipe1.createPipelineAggregatedWithoutChangesShown(jenkins.getInstance()); Pipeline aggregated2 = pipe2.createPipelineAggregatedWithChangesShown(jenkins.getInstance()); assertNull(aggregated1.getStages().get(0).getVersion()); assertNull(aggregated2.getStages().get(0).getVersion()); assertTrue(aggregated1.getStages().get(0).getTasks().get(0).getStatus().isIdle()); assertTrue(aggregated2.getStages().get(0).getTasks().get(0).getStatus().isIdle()); assertTrue(aggregated1.getStages().get(3).getTasks().get(0).getStatus().isIdle()); assertEquals("job/sonar1/", aggregated1.getStages().get(3).getTasks().get(0).getLink()); jenkins.buildAndAssertSuccess(build1); jenkins.waitUntilNoActivity(); assertNotNull(sonar.getLastBuild()); assertEquals(4, pipe1.getStages().size()); assertEquals(2, pipe2.getStages().size()); aggregated1 = pipe1.createPipelineAggregatedWithoutChangesShown(jenkins.getInstance()); aggregated2 = pipe2.createPipelineAggregatedWithChangesShown(jenkins.getInstance()); assertEquals("#1", aggregated1.getStages().get(1).getVersion()); assertEquals("job/sonar1/1/", aggregated1.getStages().get(3).getTasks().get(0).getLink()); assertEquals("1", aggregated1.getStages().get(1).getTasks().get(0).getBuildId()); assertTrue(aggregated1.getStages().get(3).getTasks().get(0).getStatus().isSuccess()); assertEquals(true, aggregated2.getStages().get(1).getTasks().get(0).getStatus().isIdle()); assertEquals("job/sonar1/", aggregated2.getStages().get(1).getTasks().get(0).getLink()); assertNull(aggregated2.getStages().get(1).getTasks().get(0).getBuildId()); assertTrue(aggregated1.getStages().get(2).getTasks().get(0).getStatus().isIdle()); jenkins.buildAndAssertSuccess(build2); jenkins.waitUntilNoActivity(); aggregated1 = pipe1.createPipelineAggregatedWithoutChangesShown(jenkins.getInstance()); aggregated2 = pipe2.createPipelineAggregatedWithoutChangesShown(jenkins.getInstance()); assertEquals("#1", aggregated1.getStages().get(1).getVersion()); assertEquals("#1", aggregated2.getStages().get(1).getVersion()); assertEquals(true, aggregated2.getStages().get(1).getTasks().get(0).getStatus().isSuccess()); assertEquals("job/sonar1/2/", aggregated2.getStages().get(1).getTasks().get(0).getLink()); assertEquals("2", aggregated2.getStages().get(1).getTasks().get(0).getBuildId()); jenkins.buildAndAssertSuccess(build1); jenkins.waitUntilNoActivity(); aggregated1 = pipe1.createPipelineAggregatedWithoutChangesShown(jenkins.getInstance()); aggregated2 = pipe2.createPipelineAggregatedWithoutChangesShown(jenkins.getInstance()); assertEquals("#2", aggregated1.getStages().get(1).getVersion()); assertEquals("#1", aggregated2.getStages().get(1).getVersion()); assertEquals("job/sonar1/3/", aggregated1.getStages().get(3).getTasks().get(0).getLink()); assertEquals("3", aggregated1.getStages().get(3).getTasks().get(0).getBuildId()); assertEquals("job/sonar1/2/", aggregated2.getStages().get(1).getTasks().get(0).getLink()); assertEquals("2", aggregated2.getStages().get(1).getTasks().get(0).getBuildId()); assertTrue(aggregated1.getStages().get(2).getTasks().get(0).getStatus().isIdle()); jenkins.buildAndAssertSuccess(build1); jenkins.waitUntilNoActivity(); assertTrue(aggregated1.getStages().get(1).getTasks().get(0).getStatus().isSuccess()); assertEquals("#2", aggregated1.getStages().get(1).getVersion()); assertTrue(aggregated1.getStages().get(2).getTasks().get(0).getStatus().isIdle()); BuildPipelineView view = new BuildPipelineView("", "", new DownstreamProjectGridBuilder("build1"), "1", false, null); view.triggerManualBuild(1, "prod", "test"); jenkins.waitUntilNoActivity(); aggregated1 = pipe1.createPipelineAggregatedWithoutChangesShown(jenkins.getInstance()); assertTrue(aggregated1.getStages().get(2).getTasks().get(0).getStatus().isSuccess()); assertEquals("#1", aggregated1.getStages().get(2).getVersion()); } @Test @Ignore("Looks like support for two manual trigger for one build has been broken in BPP 1.4.3") public void testAggregatedStageWithTwoManualTasks() throws Exception { FreeStyleProject build = jenkins.createFreeStyleProject("build"); FreeStyleProject ci1 = jenkins.createFreeStyleProject("ci1"); FreeStyleProject ci2 = jenkins.createFreeStyleProject("ci2"); ci1.addProperty(new PipelineProperty("ci1", "CI1", "")); ci2.addProperty(new PipelineProperty("ci2", "CI1", "")); build.getPublishersList().add(new BuildPipelineTrigger("ci1", null)); build.getPublishersList().add(new BuildPipelineTrigger("ci2", null)); jenkins.getInstance().rebuildDependencyGraph(); jenkins.setQuietPeriod(0); jenkins.buildAndAssertSuccess(build); jenkins.waitUntilNoActivity(); assertNotNull(build.getLastBuild()); BuildPipelineView view = new BuildPipelineView("", "", new DownstreamProjectGridBuilder("build"), "1", false, null); view.triggerManualBuild(1, "ci1", "build"); jenkins.waitUntilNoActivity(); assertNotNull(ci1.getLastBuild()); assertNull(ci2.getLastBuild()); Pipeline pipeline = Pipeline.extractPipeline("test", build); Pipeline aggregated = pipeline.createPipelineAggregatedWithoutChangesShown(jenkins.getInstance()); assertNotNull(aggregated); assertEquals("ci1", aggregated.getStages().get(1).getTasks().get(0).getName()); assertEquals("ci2", aggregated.getStages().get(1).getTasks().get(1).getName()); assertEquals("SUCCESS", aggregated.getStages().get(1).getTasks().get(0).getStatus().toString()); assertEquals("IDLE", aggregated.getStages().get(1).getTasks().get(1).getStatus().toString()); assertEquals("#1", aggregated.getStages().get(1).getVersion()); jenkins.buildAndAssertSuccess(build); jenkins.waitUntilNoActivity(); aggregated = pipeline.createPipelineAggregatedWithoutChangesShown(jenkins.getInstance()); assertNotNull(aggregated); assertEquals("#2", build.getLastBuild().getDisplayName()); assertEquals("SUCCESS", aggregated.getStages().get(1).getTasks().get(0).getStatus().toString()); assertEquals("IDLE", aggregated.getStages().get(1).getTasks().get(1).getStatus().toString()); assertEquals("#1", aggregated.getStages().get(1).getVersion()); view.triggerManualBuild(2, "ci2", "build"); jenkins.waitUntilNoActivity(); aggregated = pipeline.createPipelineAggregatedWithoutChangesShown(jenkins.getInstance()); assertNotNull(aggregated); assertEquals("IDLE", aggregated.getStages().get(1).getTasks().get(0).getStatus().toString()); assertEquals("SUCCESS", aggregated.getStages().get(1).getTasks().get(1).getStatus().toString()); assertEquals("#2", aggregated.getStages().get(1).getVersion()); } @Test public void testCreatePipelineLatest() throws Exception { FreeStyleProject build = jenkins.createFreeStyleProject("build"); build.addProperty(new PipelineProperty("", "Build", "")); FreeStyleProject sonar = jenkins.createFreeStyleProject("sonar"); sonar.addProperty(new PipelineProperty("Sonar", "Build", "")); FreeStyleProject deploy = jenkins.createFreeStyleProject("deploy"); deploy.addProperty(new PipelineProperty("Deploy", "CI", "")); jenkins.getInstance().rebuildDependencyGraph(); jenkins.setQuietPeriod(0); Pipeline pipeline = Pipeline.extractPipeline("Pipeline", build); assertNotNull(pipeline); assertEquals("Pipeline", pipeline.getName()); assertEquals(1, pipeline.getStages().size()); Stage buildStage = pipeline.getStages().get(0); assertEquals("Build", buildStage.getName()); assertEquals(1, buildStage.getTasks().size()); assertEquals("build", buildStage.getTasks().get(0).getName()); build.getPublishersList().add(new BuildTrigger("sonar,deploy", false)); jenkins.getInstance().rebuildDependencyGraph(); pipeline = Pipeline.extractPipeline("Pipeline", build); buildStage = pipeline.getStages().get(0); assertEquals("Build", buildStage.getName()); assertEquals(2, buildStage.getTasks().size()); assertEquals("build", buildStage.getTasks().get(0).getName()); assertEquals("Sonar", buildStage.getTasks().get(1).getName()); Stage ciStage = pipeline.getStages().get(1); assertEquals("CI", ciStage.getName()); assertEquals(1, ciStage.getTasks().size()); assertEquals("Deploy", ciStage.getTasks().get(0).getName()); jenkins.buildAndAssertSuccess(build); jenkins.waitUntilNoActivity(); Pipeline latest = createPipelineLatest(pipeline, jenkins.getInstance()); assertNotNull(latest); assertTrue(latest.getStages().get(0).getTasks().get(0).getStatus().isSuccess()); assertTrue(latest.getStages().get(0).getTasks().get(1).getStatus().isSuccess()); assertTrue(latest.getStages().get(1).getTasks().get(0).getStatus().isSuccess()); assertEquals("job/build/1/", latest.getStages().get(0).getTasks().get(0).getLink()); assertEquals(0, latest.getStages().get(0).getColumn()); assertEquals(1, latest.getStages().get(1).getColumn()); } @Test public void testPipelineLatestDownstreamIsDisabled() throws Exception { FreeStyleProject build = jenkins.createFreeStyleProject("build"); FreeStyleProject disabled = jenkins.createFreeStyleProject("disabled"); disabled.makeDisabled(true); build.getPublishersList().add(new BuildTrigger("disabled", false)); jenkins.getInstance().rebuildDependencyGraph(); jenkins.buildAndAssertSuccess(build); jenkins.waitUntilNoActivity(); Pipeline pipeline = Pipeline.extractPipeline("Pipeline", build); Pipeline latest = createPipelineLatest(pipeline, jenkins.getInstance()); assertNotNull(latest); assertEquals(2, latest.getStages().size()); assertEquals("SUCCESS", latest.getStages().get(0).getTasks().get(0).getStatus().toString()); assertEquals("DISABLED", latest.getStages().get(1).getTasks().get(0).getStatus().toString()); } @Test public void testFirstUpstreamBuildFirstProjectHasJustOneUpstreamJob() throws Exception { StaplerRequest request = Mockito.mock(StaplerRequest.class); final FreeStyleProject upstream = jenkins.createFreeStyleProject("upstream"); final FreeStyleProject build = jenkins.createFreeStyleProject("build"); upstream.getPublishersList().add(new BuildTrigger("build", false)); jenkins.getInstance().rebuildDependencyGraph(); jenkins.buildAndAssertSuccess(upstream); jenkins.waitUntilNoActivity(); assertNotNull(upstream.getLastBuild()); assertNotNull(build.getLastBuild()); assertEquals(build.getLastBuild(), BuildUtil.getFirstUpstreamBuild(build.getLastBuild(), build)); Pipeline pipeline = Pipeline.extractPipeline("Pipeline", build); Component component = new Component("Component", "build", null, false, 3, PAGING_DISABLED, 1); List<Pipeline> pipelines = pipeline.createPipelineLatest(1, Jenkins.getInstance(), PAGING_DISABLED, SHOW_CHANGES, component); assertEquals(1, pipelines.size()); assertEquals(1, pipelines.get(0).getTriggeredBy().size()); assertEquals(TriggerCause.TYPE_UPSTREAM, pipelines.get(0).getTriggeredBy().get(0).getType()); } @Test public void getPipelineLatestWithDifferentFolders() throws Exception { MockFolder folder1 = jenkins.createFolder("folder1"); MockFolder folder2 = jenkins.createFolder("folder2"); final FreeStyleProject job1 = folder1.createProject(FreeStyleProject.class, "job1"); final FreeStyleProject job2 = folder2.createProject(FreeStyleProject.class, "job2"); job1.getPublishersList().add(new BuildTrigger("folder2/job2", false)); jenkins.getInstance().rebuildDependencyGraph(); jenkins.setQuietPeriod(0); Pipeline prototype = Pipeline.extractPipeline("Folders", job1); assertNotNull(prototype); jenkins.buildAndAssertSuccess(job1); jenkins.waitUntilNoActivity(); assertNotNull(job1.getLastBuild()); assertNotNull(job2.getLastBuild()); Pipeline pipeline = createPipelineLatest(prototype, folder1); assertNotNull(pipeline); assertEquals(2, pipeline.getStages().size()); assertEquals("folder1/job1", pipeline.getStages().get(0).getTasks().get(0).getId()); assertEquals("folder2/job2", pipeline.getStages().get(1).getTasks().get(0).getId()); assertEquals(0, pipeline.getStages().get(0).getColumn()); assertEquals(1, pipeline.getStages().get(1).getColumn()); } @Test public void testForkJoin() throws Exception { FreeStyleProject projectA = jenkins.createFreeStyleProject("A"); FreeStyleProject projectB = jenkins.createFreeStyleProject("B"); FreeStyleProject projectC = jenkins.createFreeStyleProject("C"); FreeStyleProject projectD = jenkins.createFreeStyleProject("D"); projectA.getPublishersList().add(new BuildTrigger("B,C", false)); projectB.getPublishersList().add(new BuildTrigger("D", false)); projectC.getPublishersList().add(new BuildTrigger("D", false)); projectD.getPublishersList().add( new JoinTrigger(new DescribableList<Publisher, Descriptor<Publisher>>(Saveable.NOOP), "", false)); jenkins.getInstance().rebuildDependencyGraph(); Pipeline prototype = Pipeline.extractPipeline("ForkJoin", projectA); assertNotNull(prototype); assertEquals(4, prototype.getStages().size()); assertEquals(0, prototype.getStages().get(0).getColumn()); assertEquals(0, prototype.getStages().get(0).getRow()); assertEquals(1, prototype.getStages().get(1).getColumn()); assertEquals(0, prototype.getStages().get(1).getRow()); assertEquals(2, prototype.getStages().get(2).getColumn()); assertEquals(0, prototype.getStages().get(2).getRow()); assertEquals(1, prototype.getStages().get(3).getColumn()); assertEquals(1, prototype.getStages().get(3).getRow()); } @Test public void getPipelineLatestWithSameFolders() throws Exception { MockFolder folder1 = jenkins.createFolder("folder1"); final FreeStyleProject job1 = folder1.createProject(FreeStyleProject.class, "job1"); final FreeStyleProject job2 = folder1.createProject(FreeStyleProject.class, "job2"); job1.getPublishersList().add(new BuildTrigger("folder1/job2", false)); jenkins.getInstance().rebuildDependencyGraph(); jenkins.setQuietPeriod(0); Pipeline prototype = Pipeline.extractPipeline("Folders", job1); assertNotNull(prototype); jenkins.buildAndAssertSuccess(job1); jenkins.waitUntilNoActivity(); assertNotNull(job1.getLastBuild()); assertNotNull(job2.getLastBuild()); Pipeline pipeline = createPipelineLatest(prototype, folder1); assertNotNull(pipeline); assertEquals(2, pipeline.getStages().size()); assertEquals("folder1/job1", pipeline.getStages().get(0).getTasks().get(0).getId()); assertEquals("folder1/job2", pipeline.getStages().get(1).getTasks().get(0).getId()); assertTrue(pipeline.getStages().get(0).getTasks().get(0).getStatus().isSuccess()); assertTrue(pipeline.getStages().get(1).getTasks().get(0).getStatus().isSuccess()); } @Test public void getPipelineLatestWithNestedFolders() throws Exception { MockFolder folder1 = jenkins.createFolder("folder1"); MockFolder folder2 = folder1.createProject(MockFolder.class, "subfolder"); final FreeStyleProject job1 = folder2.createProject(FreeStyleProject.class, "job1"); final FreeStyleProject job2 = folder1.createProject(FreeStyleProject.class, "job2"); job1.getPublishersList().add(new BuildTrigger("folder1/job2", false)); jenkins.getInstance().rebuildDependencyGraph(); jenkins.setQuietPeriod(0); Pipeline prototype = Pipeline.extractPipeline("Folders", job1); assertNotNull(prototype); jenkins.buildAndAssertSuccess(job1); jenkins.waitUntilNoActivity(); assertNotNull(job1.getLastBuild()); assertNotNull(job2.getLastBuild()); Pipeline pipeline = createPipelineLatest(prototype, folder1); assertNotNull(pipeline); assertEquals(2, pipeline.getStages().size()); assertEquals("folder1/subfolder/job1", pipeline.getStages().get(0).getTasks().get(0).getId()); assertEquals("folder1/job2", pipeline.getStages().get(1).getTasks().get(0).getId()); assertTrue(pipeline.getStages().get(0).getTasks().get(0).getStatus().isSuccess()); assertTrue(pipeline.getStages().get(1).getTasks().get(0).getStatus().isSuccess()); } /** * A -> B -> D -> E * -> C * <p/> * Javascript in view needs to have a sorted list of stages based * on row and column the stage has been placed in. */ @Issue("JENKINS-22211") @Test public void testGetPipelinesWhereRowsWillBeGambled() throws Exception { final FreeStyleProject projectA = jenkins.createFreeStyleProject("a"); final FreeStyleProject projectB = jenkins.createFreeStyleProject("b"); jenkins.createFreeStyleProject("c"); final FreeStyleProject projectD = jenkins.createFreeStyleProject("d"); jenkins.createFreeStyleProject("e"); projectA.getBuildersList().add(new TriggerBuilder( new BlockableBuildTriggerConfig("b", new BlockingBehaviour("never", "never", "never"), null))); projectB.getBuildersList().add(new TriggerBuilder( new BlockableBuildTriggerConfig("c,d", new BlockingBehaviour("never", "never", "never"), null))); projectD.getBuildersList().add(new TriggerBuilder( new BlockableBuildTriggerConfig("e", new BlockingBehaviour("never", "never", "never"), null))); jenkins.getInstance().rebuildDependencyGraph(); jenkins.setQuietPeriod(0); Pipeline pipeline = Pipeline.extractPipeline("test", projectA); assertEquals("a", pipeline.getStages().get(0).getName()); assertEquals(0, pipeline.getStages().get(0).getRow()); assertEquals(0, pipeline.getStages().get(0).getColumn()); assertEquals("b", pipeline.getStages().get(1).getName()); assertEquals(0, pipeline.getStages().get(1).getRow()); assertEquals(1, pipeline.getStages().get(1).getColumn()); assertEquals("d", pipeline.getStages().get(2).getName()); assertEquals(0, pipeline.getStages().get(2).getRow()); assertEquals(2, pipeline.getStages().get(2).getColumn()); assertEquals("e", pipeline.getStages().get(3).getName()); assertEquals(0, pipeline.getStages().get(3).getRow()); assertEquals(3, pipeline.getStages().get(3).getColumn()); assertEquals("c", pipeline.getStages().get(4).getName()); assertEquals(1, pipeline.getStages().get(4).getRow()); assertEquals(2, pipeline.getStages().get(4).getColumn()); } /** * A -> B -> D -> E -> F * -> C -> G * -> H * <p/> * Javascript in view needs to have a sorted list of stages based * on row and column the stage has been placed in. */ @Test public void testGetPipelinesWhereEachRowHasMultipleStages() throws Exception { final FreeStyleProject projectA = jenkins.createFreeStyleProject("a"); final FreeStyleProject projectB = jenkins.createFreeStyleProject("b"); jenkins.createFreeStyleProject("c"); final FreeStyleProject projectD = jenkins.createFreeStyleProject("d"); final FreeStyleProject projectE = jenkins.createFreeStyleProject("e"); jenkins.createFreeStyleProject("f"); jenkins.createFreeStyleProject("g"); jenkins.createFreeStyleProject("h"); projectA.getBuildersList().add(new TriggerBuilder( new BlockableBuildTriggerConfig("b", new BlockingBehaviour("never", "never", "never"), null))); projectB.getBuildersList().add(new TriggerBuilder( new BlockableBuildTriggerConfig("c,d", new BlockingBehaviour("never", "never", "never"), null))); projectD.getBuildersList().add(new TriggerBuilder( new BlockableBuildTriggerConfig("e", new BlockingBehaviour("never", "never", "never"), null))); projectE.getBuildersList().add(new TriggerBuilder( new BlockableBuildTriggerConfig("f,g,h", new BlockingBehaviour("never", "never", "never"), null))); jenkins.getInstance().rebuildDependencyGraph(); jenkins.setQuietPeriod(0); Pipeline pipeline = Pipeline.extractPipeline("test", projectA); assertEquals("a", pipeline.getStages().get(0).getName()); assertEquals(0, pipeline.getStages().get(0).getRow()); assertEquals(0, pipeline.getStages().get(0).getColumn()); assertEquals("b", pipeline.getStages().get(1).getName()); assertEquals(0, pipeline.getStages().get(1).getRow()); assertEquals(1, pipeline.getStages().get(1).getColumn()); assertEquals("d", pipeline.getStages().get(2).getName()); assertEquals(0, pipeline.getStages().get(2).getRow()); assertEquals(2, pipeline.getStages().get(2).getColumn()); assertEquals("e", pipeline.getStages().get(3).getName()); assertEquals(0, pipeline.getStages().get(3).getRow()); assertEquals(3, pipeline.getStages().get(3).getColumn()); assertEquals("f", pipeline.getStages().get(4).getName()); assertEquals(0, pipeline.getStages().get(4).getRow()); assertEquals(4, pipeline.getStages().get(4).getColumn()); assertEquals("c", pipeline.getStages().get(5).getName()); assertEquals(1, pipeline.getStages().get(5).getRow()); assertEquals(2, pipeline.getStages().get(5).getColumn()); assertEquals("g", pipeline.getStages().get(6).getName()); assertEquals(1, pipeline.getStages().get(6).getRow()); assertEquals(4, pipeline.getStages().get(6).getColumn()); assertEquals("h", pipeline.getStages().get(7).getName()); assertEquals(2, pipeline.getStages().get(7).getRow()); assertEquals(4, pipeline.getStages().get(7).getColumn()); } /* * A --> B --> C --> D */ @Test @Issue("JENKINS-22658") public void testRecursiveStages() throws Exception { FreeStyleProject projectA = jenkins.createFreeStyleProject("A"); projectA.addProperty(new PipelineProperty("A", "A", "")); FreeStyleProject projectB = jenkins.createFreeStyleProject("B"); projectB.addProperty(new PipelineProperty("B", "B", "")); FreeStyleProject projectC = jenkins.createFreeStyleProject("C"); projectC.addProperty(new PipelineProperty("C", "C", "")); FreeStyleProject projectD = jenkins.createFreeStyleProject("D"); projectD.addProperty(new PipelineProperty("D", "B", "")); projectA.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger( new BuildTriggerConfig("B", ResultCondition.SUCCESS, new ArrayList<AbstractBuildParameterFactory>()))); projectB.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger( new BuildTriggerConfig("C", ResultCondition.SUCCESS, new ArrayList<AbstractBuildParameterFactory>()))); projectC.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger( new BuildTriggerConfig("D", ResultCondition.SUCCESS, new ArrayList<AbstractBuildParameterFactory>()))); jenkins.getInstance().rebuildDependencyGraph(); try { Pipeline.extractPipeline("Test", projectA); fail(); } catch (StackOverflowError e) { fail("Should not throw StackOverflowError"); } catch (PipelineException e) { //Should throw this } } @Test public void testShouldShowPipelineInstanceInQueue() throws Exception { StaplerRequest request = Mockito.mock(StaplerRequest.class); final FreeStyleProject projectA = jenkins.createFreeStyleProject("A"); Pipeline prototype = Pipeline.extractPipeline("Pipe", projectA); projectA.scheduleBuild(2, new Cause.UserIdCause()); Component component = new Component( "Component",prototype.getFirstProject().getFullName(), null, false, 3, PAGING_DISABLED, 1); List<Pipeline> pipelines = prototype .createPipelineLatest(5, Jenkins.getInstance(), PAGING_DISABLED, SHOW_CHANGES, component); assertEquals(1, pipelines.size()); } private Pipeline createPipelineLatest(Pipeline pipeline, ItemGroup itemGroup) throws PipelineException { StaplerRequest request = Mockito.mock(StaplerRequest.class); Component component = new Component( "Component", pipeline.getFirstProject().getFullName(), null, false, 3, PAGING_DISABLED, 1); List<Pipeline> pipelines = pipeline .createPipelineLatest(1, itemGroup, PAGING_DISABLED, SHOW_CHANGES, component); assertFalse(pipelines.isEmpty()); return pipelines.get(0); } @Test public void testCalculatePipelineRoutesSimpleRoute() throws Exception { /* stage1 stage2 stage3 task1 -- task2 -- task3 */ Stage stage1 = mock(Stage.class); Stage stage2 = mock(Stage.class); Stage stage3 = mock(Stage.class); Task task1 = mock(Task.class); Task task2 = mock(Task.class); Task task3 = mock(Task.class); when(task1.getId()).thenReturn("task1"); when(task2.getId()).thenReturn("task2"); when(task3.getId()).thenReturn("task3"); when(task2.getDownstreamTasks()).thenReturn(Arrays.asList("task3")); when(task1.getDownstreamTasks()).thenReturn(Arrays.asList("task2")); when(stage1.getTasks()).thenReturn(Arrays.asList(task1)); when(stage2.getTasks()).thenReturn(Arrays.asList(task2)); when(stage3.getTasks()).thenReturn(Arrays.asList(task3)); FreeStyleProject project = jenkins.createFreeStyleProject("A"); Pipeline pipeline = new Pipeline("SimpleRoute", project, null, Arrays.asList(stage1, stage2, stage3)); List<Route> allRoutes = new ArrayList<Route>(); pipeline.calculatePipelineRoutes(task1, null, allRoutes); /* task1 -> task2 -> task3 */ assertEquals(1, allRoutes.size()); } @Test public void testCalculatePipelineRoutesComplexRoutes() throws Exception { /* stage1 stage2 stage3 stage4 task1 -- task2 -- task4 -- task6 |_ task3 |_ task5 |_ task7 */ Stage stage1 = mock(Stage.class); Stage stage2 = mock(Stage.class); Stage stage3 = mock(Stage.class); Stage stage4 = mock(Stage.class); Task task1 = mock(Task.class); Task task2 = mock(Task.class); Task task3 = mock(Task.class); Task task4 = mock(Task.class); Task task5 = mock(Task.class); Task task6 = mock(Task.class); Task task7 = mock(Task.class); Status status1 = mock(Status.class); Status status2 = mock(Status.class); Status status3 = mock(Status.class); Status status4 = mock(Status.class); Status status5 = mock(Status.class); Status status6 = mock(Status.class); Status status7 = mock(Status.class); when(task1.getId()).thenReturn("task1"); when(task2.getId()).thenReturn("task2"); when(task3.getId()).thenReturn("task3"); when(task4.getId()).thenReturn("task4"); when(task5.getId()).thenReturn("task5"); when(task6.getId()).thenReturn("task6"); when(task7.getId()).thenReturn("task7"); when(status1.getDuration()).thenReturn(100L); when(status2.getDuration()).thenReturn(200L); when(status3.getDuration()).thenReturn(300L); when(status4.getDuration()).thenReturn(400L); when(status5.getDuration()).thenReturn(500L); when(status6.getDuration()).thenReturn(600L); when(status7.getDuration()).thenReturn(700L); when(task1.getStatus()).thenReturn(status1); when(task2.getStatus()).thenReturn(status2); when(task3.getStatus()).thenReturn(status3); when(task4.getStatus()).thenReturn(status4); when(task5.getStatus()).thenReturn(status5); when(task6.getStatus()).thenReturn(status6); when(task7.getStatus()).thenReturn(status7); when(task6.getDownstreamTasks()).thenReturn(Arrays.asList("task7")); when(task4.getDownstreamTasks()).thenReturn(Arrays.asList("task6")); when(task2.getDownstreamTasks()).thenReturn(Arrays.asList("task4", "task5")); when(task1.getDownstreamTasks()).thenReturn(Arrays.asList("task2", "task3")); when(stage1.getTasks()).thenReturn(Arrays.asList(task1)); when(stage2.getTasks()).thenReturn(Arrays.asList(task2, task3)); when(stage3.getTasks()).thenReturn(Arrays.asList(task4, task5)); when(stage4.getTasks()).thenReturn(Arrays.asList(task6, task7)); FreeStyleProject project = jenkins .createFreeStyleProject("A"); Pipeline pipeline = new Pipeline("TotalBuildTime", project, null, Arrays.asList(stage1, stage2, stage3, stage4)); /* task1 -> task3: 100 + 300 = 400L task1 -> task2 -> task5: 100 + 200 + 500 = 800L task1 -> task2 -> task4 -> task6 -> task7: 100 + 200 + 400 + 600 + 700 = 2000L */ pipeline.calculateTotalBuildTime(); assertEquals(2000L, pipeline.getTotalBuildTime()); } @Test public void testCalculateTotalBuildTimeNoStages() throws Exception { FreeStyleProject project = jenkins.createFreeStyleProject("A"); Pipeline pipeline = new Pipeline("NoStages", project, null, new ArrayList<Stage>()); pipeline.calculateTotalBuildTime(); assertEquals(0L, pipeline.getTotalBuildTime()); } @Test @Issue("JENKINS-30043") public void testSubProjectsFirst() throws Exception { FreeStyleProject jobA = jenkins.createFreeStyleProject("Job A"); jobA.addProperty(new PipelineProperty(null, "Stage", null)); FreeStyleProject util1 = jenkins.createFreeStyleProject("Job Util 1"); util1.addProperty(new PipelineProperty(null, "Stage", null)); FreeStyleProject util2 = jenkins.createFreeStyleProject("Job Util 2"); util2.addProperty(new PipelineProperty(null, "Stage", null)); FreeStyleProject jobC = jenkins.createFreeStyleProject("Job C"); jobC.addProperty(new PipelineProperty(null, "Stage", null)); jobA.getBuildersList().add(new TriggerBuilder( new BlockableBuildTriggerConfig("Job Util 1", new BlockingBehaviour("never", "never", "never"), null))); jobA.getBuildersList().add(new TriggerBuilder( new BlockableBuildTriggerConfig("Job Util 2", new BlockingBehaviour("never", "never", "never"), null))); jobA.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger( new BuildTriggerConfig("Job C", ResultCondition.SUCCESS, new ArrayList<AbstractBuildParameterFactory>()))); jenkins.getInstance().rebuildDependencyGraph(); Pipeline pipeline = Pipeline.extractPipeline("Pipeline", jobA); assertEquals("Job A", pipeline.getStages().get(0).getTasks().get(0).getId()); assertEquals("Job Util 1", pipeline.getStages().get(0).getTasks().get(1).getId()); assertEquals("Job Util 2", pipeline.getStages().get(0).getTasks().get(2).getId()); assertEquals("Job C", pipeline.getStages().get(0).getTasks().get(3).getId()); } }