@Issue("JENKINS-46547") @Test public void multiplePipelinesExecutedInLibraryShouldFail() throws Exception { otherRepo.init(); otherRepo.write("vars/fromLib.groovy", pipelineSourceFromResources("libForMultiplePipelinesExecutedInLibrary")); otherRepo.git("add", "vars"); otherRepo.git("commit", "--message=init"); LibraryConfiguration firstLib = new LibraryConfiguration("from-lib", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))); GlobalLibraries.get().setLibraries(Arrays.asList(firstLib)); expect(Result.FAILURE, "pipelineDefinedInLibrary") .logContains("java.lang.IllegalStateException: Only one pipeline { ... } block can be executed in a single run") .go(); }
@Issue("JENKINS-40642") @Test public void libraryAnnotation() throws Exception { otherRepo.init(); otherRepo.write("vars/myecho.groovy", "def call() {echo 'something special'}"); otherRepo.write("vars/myecho.txt", "Says something very special!"); otherRepo.git("add", "vars"); otherRepo.git("commit", "--message=init"); GlobalLibraries.get().setLibraries(Collections.singletonList( new LibraryConfiguration("echo-utils", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))))); expect("libraryAnnotation") .logContains("something special") .go(); }
@Test public void serializationLibrariesGString() throws Exception { otherRepo.init(); otherRepo.write("vars/myecho.groovy", "def call() {echo 'something special'}"); otherRepo.write("vars/myecho.txt", "Says something very special!"); otherRepo.git("add", "vars"); otherRepo.git("commit", "--message=init"); LibraryConfiguration firstLib = new LibraryConfiguration("echo-utils", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))); thirdRepo.init(); thirdRepo.write("vars/whereFrom.groovy", "def call() {echo 'from another library'}"); thirdRepo.write("vars/whereFrom.txt", "Says where it's from!"); thirdRepo.git("add", "vars"); thirdRepo.git("commit", "--message=init"); LibraryConfiguration secondLib = new LibraryConfiguration("test", new SCMSourceRetriever(new GitSCMSource(null, thirdRepo.toString(), "", "*", "", true))); secondLib.setDefaultVersion("master"); GlobalLibraries.get().setLibraries(Arrays.asList(firstLib, secondLib)); expect("serializationLibrariesGString") .logContains("something special", "from another library") .go(); }
@Issue("JENKINS-46547") @Test public void pipelineDefinedInLibrary() throws Exception { otherRepo.init(); otherRepo.write("vars/fromLib.groovy", pipelineSourceFromResources("libForPipelineDefinedInLibrary")); otherRepo.git("add", "vars"); otherRepo.git("commit", "--message=init"); LibraryConfiguration firstLib = new LibraryConfiguration("from-lib", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))); GlobalLibraries.get().setLibraries(Arrays.asList(firstLib)); expect("pipelineDefinedInLibrary") .logContains("[Pipeline] { (One)", "[Pipeline] { (Two)") .logNotContains("World") .go(); }
@Issue("JENKINS-38110") @Test public void librariesDirective() throws Exception { otherRepo.init(); otherRepo.write("vars/myecho.groovy", "def call() {echo 'something special'}"); otherRepo.write("vars/myecho.txt", "Says something very special!"); otherRepo.git("add", "vars"); otherRepo.git("commit", "--message=init"); LibraryConfiguration firstLib = new LibraryConfiguration("echo-utils", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))); thirdRepo.init(); thirdRepo.write("vars/whereFrom.groovy", "def call() {echo 'from another library'}"); thirdRepo.write("vars/whereFrom.txt", "Says where it's from!"); thirdRepo.git("add", "vars"); thirdRepo.git("commit", "--message=init"); LibraryConfiguration secondLib = new LibraryConfiguration("whereFrom", new SCMSourceRetriever(new GitSCMSource(null, thirdRepo.toString(), "", "*", "", true))); secondLib.setDefaultVersion("master"); GlobalLibraries.get().setLibraries(Arrays.asList(firstLib, secondLib)); expect("librariesDirective") .logContains("something special", "from another library") .go(); }
@Issue("JENKINS-40657") @Test public void libraryObjectDefinedOutsidePipeline() throws Exception { otherRepo.init(); otherRepo.write("src/org/foo/Zot.groovy", "package org.foo;\n" + "\n" + "class Zot implements Serializable {\n" + " def steps\n" + " Zot(steps){\n" + " this.steps = steps\n" + " }\n" + " def echo(msg) {\n" + " steps.echo \"${msg}\"\n" + " }\n" + "}\n"); otherRepo.git("add", "src"); otherRepo.git("commit", "--message=init"); GlobalLibraries.get().setLibraries(Collections.singletonList( new LibraryConfiguration("zot-stuff", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))))); expect("libraryObjectDefinedOutsidePipeline") .logContains("hello"); }
@Issue("JENKINS-40657") @Test public void libraryObjectInScript() throws Exception { otherRepo.init(); otherRepo.write("src/org/foo/Zot.groovy", "package org.foo;\n" + "\n" + "class Zot implements Serializable {\n" + " def steps\n" + " Zot(steps){\n" + " this.steps = steps\n" + " }\n" + " def echo(msg) {\n" + " steps.echo \"${msg}\"\n" + " }\n" + "}\n"); otherRepo.git("add", "src"); otherRepo.git("commit", "--message=init"); GlobalLibraries.get().setLibraries(Collections.singletonList( new LibraryConfiguration("zot-stuff", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))))); expect("libraryObjectInScript") .logContains("hello") .go(); }
@Issue("JENKINS-43035") @Test public void libraryObjectImportInWhenExpr() throws Exception { otherRepo.init(); otherRepo.write("src/org/foo/Zot.groovy", "package org.foo;\n" + "\n" + "class Zot implements Serializable {\n" + " def steps\n" + " Zot(steps){\n" + " this.steps = steps\n" + " }\n" + " def echo(msg) {\n" + " steps.echo \"${msg}\"\n" + " }\n" + "}\n"); otherRepo.git("add", "src"); otherRepo.git("commit", "--message=init"); GlobalLibraries.get().setLibraries(Collections.singletonList( new LibraryConfiguration("zot-stuff", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))))); expect("libraryObjectImportInWhenExpr") .logContains("hello") .go(); }
@Issue("JENKINS-46547") @Test public void pipelineDefinedInLibraryInFolder() throws Exception { otherRepo.init(); otherRepo.write("vars/fromLib.groovy", pipelineSourceFromResources("libForPipelineDefinedInLibrary")); otherRepo.git("add", "vars"); otherRepo.git("commit", "--message=init"); LibraryConfiguration firstLib = new LibraryConfiguration("from-lib", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))); Folder folder = j.jenkins.createProject(Folder.class, "libInFolder"); folder.getProperties().add(new FolderLibraries(Collections.singletonList(firstLib))); expect("pipelineDefinedInLibrary") .inFolder(folder) .logContains("[Pipeline] { (One)", "[Pipeline] { (Two)") .logNotContains("World") .go(); }
@Test public void configRoundtrip() throws Exception { WorkflowMultiBranchProject mp = r.jenkins.createProject(WorkflowMultiBranchProject.class, "p"); BranchSource bs = new BranchSource(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", false)); mp.getSourcesList().add(bs); bs.setStrategy(new DefaultBranchPropertyStrategy(new BranchProperty[]{new DurabilityHintBranchProperty(FlowDurabilityHint.SURVIVABLE_NONATOMIC)})); r.configRoundtrip(mp); DefaultBranchPropertyStrategy strat = (DefaultBranchPropertyStrategy)(mp.getBranchPropertyStrategy(mp.getSCMSources().get(0))); DurabilityHintBranchProperty prop = null; for (BranchProperty bp : strat.getProps()) { if (bp instanceof DurabilityHintBranchProperty) { prop = (DurabilityHintBranchProperty)bp; break; } } Assert.assertNotNull(prop); Assert.assertEquals(FlowDurabilityHint.SURVIVABLE_NONATOMIC, prop.getHint()); }
@Override public void evaluate() throws Throwable { sampleGitRepo.init(); sampleGitRepo.write("Jenkinsfile", "def _scm = scm; semaphore 'wait'; node {checkout _scm; echo readFile('file')}"); sampleGitRepo.write("file", "initial content"); sampleGitRepo.git("add", "Jenkinsfile"); sampleGitRepo.git("commit", "--all", "--message=flow"); WorkflowMultiBranchProject mp = story.j.jenkins.createProject(WorkflowMultiBranchProject.class, "p"); mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleGitRepo.toString(), "", "*", "", false), new DefaultBranchPropertyStrategy(new BranchProperty[0]))); WorkflowJob p = WorkflowMultiBranchProjectTest.scheduleAndFindBranchProject(mp, "master"); SemaphoreStep.waitForStart("wait/1", null); WorkflowRun b1 = p.getLastBuild(); assertNotNull(b1); } });
@Issue("JENKINS-42473") @Test public void folderLibraryParsing() throws Exception { otherRepo.init(); otherRepo.git("checkout", "-b", "test"); otherRepo.write("src/org/foo/Zot.groovy", "package org.foo;\n" + "\n" + "def echo(msg) {\n" + " echo \"-> ${msg}\"\n" + "}\n"); otherRepo.git("add", "src"); otherRepo.git("commit", "--message=init"); Folder folder = j.jenkins.createProject(Folder.class, "testFolder"); LibraryConfiguration echoLib = new LibraryConfiguration("zot-stuff", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))); folder.getProperties().add(new FolderLibraries(Collections.singletonList(echoLib))); WorkflowRun firstRun = expect("folderLibraryParsing") .inFolder(folder) .logContains("Hello world") .go(); WorkflowRun secondRun = j.buildAndAssertSuccess(firstRun.getParent()); ExecutionModelAction action = secondRun.getAction(ExecutionModelAction.class); assertNotNull(action); ModelASTStages stages = action.getStages(); assertNull(stages.getSourceLocation()); assertNotNull(stages); }
@Issue("JENKINS-46547") @Test public void multiplePipelinesDefinedInLibrary() throws Exception { otherRepo.init(); otherRepo.write("vars/fromLib.groovy", pipelineSourceFromResources("libForMultiplePipelinesDefinedInLibrary")); otherRepo.git("add", "vars"); otherRepo.git("commit", "--message=init"); LibraryConfiguration firstLib = new LibraryConfiguration("from-lib", new SCMSourceRetriever(new GitSCMSource(null, otherRepo.toString(), "", "*", "", true))); GlobalLibraries.get().setLibraries(Arrays.asList(firstLib)); WorkflowRun firstRun = expect("multiplePipelinesDefinedInLibraryFirst") .runFromRepo(false) .logContains("[Pipeline] { (One)", "[Pipeline] { (Two)") .logNotContains("World") .go(); ExecutionModelAction firstAction = firstRun.getAction(ExecutionModelAction.class); assertNotNull(firstAction); ModelASTStages firstStages = firstAction.getStages(); assertNotNull(firstStages); assertEquals(2, firstStages.getStages().size()); WorkflowRun secondRun = expect("multiplePipelinesDefinedInLibrarySecond") .runFromRepo(false) .logContains("[Pipeline] { (Different)", "This is the alternative pipeline") .go(); ExecutionModelAction secondAction = secondRun.getAction(ExecutionModelAction.class); assertNotNull(secondAction); ModelASTStages secondStages = secondAction.getStages(); assertNotNull(secondStages); assertEquals(1, secondStages.getStages().size()); }
@Test public void deletedJenkinsfile() throws Exception { sampleGitRepo.init(); sampleGitRepo.write("Jenkinsfile", "node { echo 'Hello World' }"); sampleGitRepo.git("add", "Jenkinsfile"); sampleGitRepo.git("commit", "--all", "--message=flow"); WorkflowMultiBranchProject mp = r.jenkins.createProject(WorkflowMultiBranchProject.class, "p"); mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleGitRepo.toString(), "", "*", "", false))); WorkflowJob p = WorkflowMultiBranchProjectTest.scheduleAndFindBranchProject(mp, "master"); assertEquals(1, mp.getItems().size()); r.waitUntilNoActivity(); WorkflowRun b1 = p.getLastBuild(); assertEquals(1, b1.getNumber()); sampleGitRepo.git("rm", "Jenkinsfile"); sampleGitRepo.git("commit", "--all", "--message=remove"); WorkflowRun b2 = r.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get()); r.assertLogContains("Jenkinsfile not found", b2); }
@Test public void durabilityHintByPropertyStep() throws Exception { sampleRepo.init(); sampleRepo.write("Jenkinsfile", "properties([durabilityHint('" + FlowDurabilityHint.SURVIVABLE_NONATOMIC.getName()+"')])\n"+ "echo 'whynot'"); sampleRepo.git("add", "Jenkinsfile"); sampleRepo.git("commit", "--all", "--message=flow"); WorkflowMultiBranchProject mp = r.jenkins.createProject(WorkflowMultiBranchProject.class, "p"); mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", false))); WorkflowJob p = scheduleAndFindBranchProject(mp, "master"); r.waitUntilNoActivity(); WorkflowRun b1 = p.getLastBuild(); Assert.assertEquals(Result.SUCCESS, b1.getResult()); DurabilityHintJobProperty prop = p.getProperty(DurabilityHintJobProperty.class); Assert.assertEquals(FlowDurabilityHint.SURVIVABLE_NONATOMIC, prop.getHint()); }
@Override public void evaluate() throws Throwable { sampleRepo.init(); sampleRepo.git("checkout", "-b", "dev/main"); String script = "echo \"branch=${env.BRANCH_NAME}\"\n" + "node {\n" + " checkout scm\n" + " echo \"workspace=${pwd().replaceFirst('.+dev', 'dev')}\"\n" + "}"; sampleRepo.write("Jenkinsfile", script); sampleRepo.git("add", "Jenkinsfile"); sampleRepo.git("commit", "--all", "--message=flow"); WorkflowMultiBranchProject mp = story.j.jenkins.createProject(WorkflowMultiBranchProject.class, "p"); GitSCMSource source = new GitSCMSource(sampleRepo.toString()); source.setTraits(Collections.singletonList(new BranchDiscoveryTrait())); mp.getSourcesList().add(new BranchSource(source)); WorkflowJob p = scheduleAndFindBranchProject(mp, "dev%2Fmain"); assertEquals(1, mp.getItems().size()); story.j.waitUntilNoActivity(); WorkflowRun b1 = p.getLastBuild(); assertEquals(1, b1.getNumber()); story.j.assertLogContains("branch=dev/main", b1); story.j.assertLogContains("workspace=dev_main", b1); verifyProject(p); sampleRepo.write("Jenkinsfile", script.replace("branch=", "Branch=")); } });
@Test @Issue("JENKINS-48826") public void durabilityHintByBranchProperty() throws Exception { sampleRepo.init(); sampleRepo.write("Jenkinsfile", "echo 'whynot'"); sampleRepo.git("add", "Jenkinsfile"); sampleRepo.git("commit", "--all", "--message=flow"); WorkflowMultiBranchProject mp = r.jenkins.createProject(WorkflowMultiBranchProject.class, "p"); BranchSource bs = new BranchSource(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", false)); mp.getSourcesList().add(bs); bs.setStrategy(new DefaultBranchPropertyStrategy(new BranchProperty[]{new DurabilityHintBranchProperty(FlowDurabilityHint.SURVIVABLE_NONATOMIC)})); WorkflowJob p = scheduleAndFindBranchProject(mp, "master"); r.waitUntilNoActivity(); Assert.assertEquals(FlowDurabilityHint.SURVIVABLE_NONATOMIC, DurabilityHintProvider.suggestedFor(p)); WorkflowRun b1 = p.getLastBuild(); Assert.assertEquals(Result.SUCCESS, b1.getResult()); // Ensure when we remove the property, branches see that on the next build bs.setStrategy(new DefaultBranchPropertyStrategy(new BranchProperty[]{})); p = scheduleAndFindBranchProject(mp, "master"); r.waitUntilNoActivity(); Assert.assertEquals(GlobalDefaultFlowDurabilityLevel.getDefaultDurabilityHint(), DurabilityHintProvider.suggestedFor(mp.getItems().iterator().next())); } }
@Test public void multibranch() throws Exception { sampleRepo.init(); sampleRepo.write("Jenkinsfile", "node {checkout scm; echo readFile('file')}"); sampleRepo.write("file", "initial content"); sampleRepo.git("add", "Jenkinsfile"); sampleRepo.git("commit", "--all", "--message=init"); WorkflowMultiBranchProject mp = r.jenkins.createProject(WorkflowMultiBranchProject.class, "p"); mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", false), new DefaultBranchPropertyStrategy(new BranchProperty[0]))); WorkflowJob p = WorkflowMultiBranchProjectTest.scheduleAndFindBranchProject(mp, "master"); r.waitUntilNoActivity(); WorkflowRun b1 = p.getLastBuild(); assertNotNull(b1); assertEquals(1, b1.getNumber()); r.assertLogContains("initial content", b1); sampleRepo.write("file", "subsequent content"); sampleRepo.git("add", "file"); sampleRepo.git("commit", "--message=next"); // Replaying main script with some upcasing. WorkflowRun b2 = (WorkflowRun) b1.getAction(ReplayAction.class).run("node {checkout scm; echo readFile('file').toUpperCase()}", Collections.<String,String>emptyMap()).get(); assertEquals(2, b2.number); // For a multibranch project, we expect checkout scm to retrieve the same repository revision as the (original) Jenkinsfile. r.assertLogContains("INITIAL CONTENT", b2); }
@SuppressWarnings("deprecation") // RunList.size @Test public void useBuildDiscarder() throws Exception { sampleRepo.init(); sampleRepo.write("Jenkinsfile", "properties([buildDiscarder(logRotator(numToKeepStr: '1'))])"); sampleRepo.git("add", "Jenkinsfile"); sampleRepo.git("commit", "--all", "--message=flow"); WorkflowMultiBranchProject mp = r.jenkins.createProject(WorkflowMultiBranchProject.class, "p"); mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", false))); WorkflowJob p = scheduleAndFindBranchProject(mp, "master"); assertEquals(1, mp.getItems().size()); r.waitUntilNoActivity(); // #1 built automatically assertEquals(1, p.getBuilds().size()); r.assertBuildStatusSuccess(p.scheduleBuild2(0)); // #2 assertEquals(1, p.getBuilds().size()); r.assertBuildStatusSuccess(p.scheduleBuild2(0)); // #3 assertEquals(1, p.getBuilds().size()); WorkflowRun b3 = p.getLastBuild(); assertEquals(3, b3.getNumber()); assertNull(b3.getPreviousBuild()); }
prepRepoWithJenkinsfile("restart", "sameCheckoutMultibranch"); WorkflowMultiBranchProject mp = j.jenkins.createProject(WorkflowMultiBranchProject.class, "sameCheckoutParent"); mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", false))); WorkflowJob p = WorkflowMultiBranchProjectTest.scheduleAndFindBranchProject(mp, "master"); j.waitUntilNoActivity();