Refine search
@Test public void parameterized() throws Exception { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p"); p.addProperty(new ParametersDefinitionProperty(new StringParameterDefinition("param", ""))); p.setDefinition(new CpsFlowDefinition("echo \"run with ${param}\"", true)); WorkflowRun b1 = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0, new ParametersAction(new StringParameterValue("param", "some value")))); story.j.assertLogContains("run with some value", b1); // When we replay a parameterized build, we expect the original parameter values to be set. WorkflowRun b2 = (WorkflowRun) b1.getAction(ReplayAction.class).run("echo \"run again with ${param}\"", Collections.<String,String>emptyMap()).get(); story.j.assertLogContains("run again with some value", story.j.assertBuildStatusSuccess(b2)); } }); }
/** Verify that if the master dies messily and we're not durable against that, build fails cleanly. */ @Test public void testDurableAgainstCleanRestartFailsWithDirtyShutdown() throws Exception { final String[] logStart = new String[1]; story.addStepWithDirtyShutdown(new Statement() { @Override public void evaluate() throws Throwable { WorkflowRun run = createAndRunSleeperJob(story.j.jenkins, "durableAgainstClean", FlowDurabilityHint.PERFORMANCE_OPTIMIZED); Assert.assertEquals(FlowDurabilityHint.PERFORMANCE_OPTIMIZED, run.getExecution().getDurabilityHint()); logStart[0] = JenkinsRule.getLog(run); } }); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { WorkflowRun run = story.j.jenkins.getItemByFullName("durableAgainstClean", WorkflowJob.class).getLastBuild(); verifyFailedCleanly(story.j.jenkins, run); story.j.assertLogContains(logStart[0], run); } }); }
@Test public void nonCps() { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { p = jenkins().createProject(WorkflowJob.class, "demo"); p.setDefinition(new CpsFlowDefinition( "echo \"first parse: ${parse('foo <version>1.0</version> bar')}\"\n" + "echo \"second parse: ${parse('foo bar')}\"\n" + "@NonCPS def parse(text) {\n" + " def matcher = text =~ '<version>(.+)</version>'\n" + " matcher ? matcher[0][1] : null\n" + "}\n", true)); b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0)); story.j.assertLogContains("first parse: 1.0", b); story.j.assertLogContains("second parse: null", b); } }); }
/** * Sanity check that fully durable pipelines can survive hard kills. */ @Test public void testFullyDurableSurvivesDirtyRestart() throws Exception { final String jobName = "survivesEverything"; final String[] logStart = new String[1]; story.addStepWithDirtyShutdown(new Statement() { @Override public void evaluate() throws Throwable { Jenkins jenkins = story.j.jenkins; WorkflowRun run = createAndRunSleeperJob(story.j.jenkins, jobName, FlowDurabilityHint.MAX_SURVIVABILITY); FlowExecution exec = run.getExecution(); if (exec instanceof CpsFlowExecution) { assert ((CpsFlowExecution) exec).getStorage().isPersistedFully(); } logStart[0] = JenkinsRule.getLog(run); } }); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { WorkflowRun run = story.j.jenkins.getItemByFullName(jobName, WorkflowJob.class).getLastBuild(); verifySafelyResumed(story.j, run, false, logStart[0]); } }); }
@Test public void timing() { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { logger.record(CpsFlowExecution.TIMING_LOGGER, Level.FINE).capture(100); WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("semaphore 'wait'", true)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("wait/1", b); } }); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { WorkflowJob p = story.j.jenkins.getItemByFullName("p", WorkflowJob.class); WorkflowRun b = p.getLastBuild(); SemaphoreStep.success("wait/1", null); story.j.assertBuildStatusSuccess(story.j.waitForCompletion(b)); assertThat(logger.getRecords(), Matchers.hasSize(Matchers.equalTo(1))); assertEquals(CpsFlowExecution.TimingKind.values().length, ((CpsFlowExecution) b.getExecution()).timings.keySet().size()); } }); }
@Test public void testResumeBlocked() throws Exception { final String jobName = "survivesEverything"; final String[] logStart = new String[1]; final List<FlowNode> nodesOut = new ArrayList<FlowNode>(); story.addStepWithDirtyShutdown(new Statement() { @Override public void evaluate() throws Throwable { Jenkins jenkins = story.j.jenkins; WorkflowRun run = createAndRunSleeperJob(story.j.jenkins, jobName, FlowDurabilityHint.MAX_SURVIVABILITY); run.getParent().setResumeBlocked(true); FlowExecution exec = run.getExecution(); if (exec instanceof CpsFlowExecution) { assert ((CpsFlowExecution) exec).getStorage().isPersistedFully(); } logStart[0] = JenkinsRule.getLog(run); nodesOut.addAll(new DepthFirstScanner().allNodes(run.getExecution())); nodesOut.sort(FlowScanningUtils.ID_ORDER_COMPARATOR); } }); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { WorkflowRun run = story.j.jenkins.getItemByFullName(jobName, WorkflowJob.class).getLastBuild(); verifyFailedCleanly(story.j.jenkins, run); assertIncludesNodes(nodesOut, run); } }); }
@Test public void localMethodCallWithinBranch() { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { p = jenkins().createProject(WorkflowJob.class, "demo"); p.setDefinition(new CpsFlowDefinition(join( "def touch(f) { writeFile text: '', file: f }", "node {", " parallel(aa: {touch('a')}, bb: {touch('b')})", "}" ), false)); startBuilding().get(); assertBuildCompletedSuccessfully(); assertTrue(jenkins().getWorkspaceFor(p).child("a").exists()); assertTrue(jenkins().getWorkspaceFor(p).child("b").exists()); } }); }
/** Verify that if the master dies messily and FlowNode storage is lost entirely we fail the build cleanly. */ @Test @Issue("JENKINS-48824") public void testDurableAgainstCleanRestartFailsWithBogusStorageFile() throws Exception { final String[] logStart = new String[1]; story.addStepWithDirtyShutdown(new Statement() { @Override public void evaluate() throws Throwable { WorkflowRun run = createAndRunSleeperJob(story.j.jenkins, "durableAgainstClean", FlowDurabilityHint.PERFORMANCE_OPTIMIZED); Assert.assertEquals(FlowDurabilityHint.PERFORMANCE_OPTIMIZED, run.getExecution().getDurabilityHint()); logStart[0] = JenkinsRule.getLog(run); CpsFlowExecution exec = (CpsFlowExecution)(run.getExecution()); // Ensure the storage file is unreadable try (FileChannel fis = new FileOutputStream(new File(exec.getStorageDir(), "flowNodeStore.xml")).getChannel()) { fis.truncate(5); // Leave a tiny bit just to make things more interesting } } }); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { WorkflowRun run = story.j.jenkins.getItemByFullName("durableAgainstClean", WorkflowJob.class).getLastBuild(); verifyFailedCleanly(story.j.jenkins, run); story.j.assertLogContains(logStart[0], run); } }); }
@Test public void authentication() throws Exception { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { jenkins().setSecurityRealm(story.j.createDummySecurityRealm()); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { assertEquals(JenkinsRule.DummySecurityRealm.class, jenkins().getSecurityRealm().getClass());
/** * Verifies that if we're only durable against clean restarts, the pipeline will survive it. */ @Test public void testDurableAgainstCleanRestartSurvivesIt() throws Exception { final String jobName = "durableAgainstClean"; final String[] logStart = new String[1]; story.addStep(new Statement() { @Override public void evaluate() throws Throwable { Jenkins jenkins = story.j.jenkins; WorkflowRun run = createAndRunSleeperJob(story.j.jenkins, jobName, FlowDurabilityHint.PERFORMANCE_OPTIMIZED); FlowExecution exec = run.getExecution(); assertBaseStorageType(exec, BulkFlowNodeStorage.class); logStart[0] = JenkinsRule.getLog(run); } }); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { WorkflowRun run = story.j.jenkins.getItemByFullName(jobName, WorkflowJob.class).getLastBuild(); Assert.assertEquals(FlowDurabilityHint.PERFORMANCE_OPTIMIZED, run.getExecution().getDurabilityHint()); assertBaseStorageType(run.getExecution(), BulkFlowNodeStorage.class); verifySafelyResumed(story.j, run, true, logStart[0]); } }); }
/** Sanity check that fully durable pipelines shutdown and restart cleanly */ @Test public void testFullyDurableSurvivesCleanRestart() throws Exception { final String jobName = "survivesEverything"; final String[] logStart = new String[1]; story.addStep(new Statement() { @Override public void evaluate() throws Throwable { Jenkins jenkins = story.j.jenkins; WorkflowRun run = createAndRunBasicJob(story.j.jenkins, jobName, FlowDurabilityHint.MAX_SURVIVABILITY); FlowExecution exec = run.getExecution(); if (exec instanceof CpsFlowExecution) { assert ((CpsFlowExecution) exec).getStorage().isPersistedFully(); } logStart[0] = JenkinsRule.getLog(run); } }); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { WorkflowRun run = story.j.jenkins.getItemByFullName(jobName, WorkflowJob.class).getLastBuild(); verifySafelyResumed(story.j, run, true, logStart[0]); } }); }
@Test public void localMethodCallWithinLotsOfBranches() { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { p = jenkins().createProject(WorkflowJob.class, "demo"); p.setDefinition(new CpsFlowDefinition( IOUtils.toString(getClass().getResource("localMethodCallWithinLotsOfBranches.groovy")), false)); startBuilding().get(); assertBuildCompletedSuccessfully(); // count number of shell steps FlowGraphTable t = buildTable(); int shell=0; for (Row r : t.getRows()) { if (r.getNode() instanceof StepAtomNode) { StepDescriptor descriptor = ((StepAtomNode)r.getNode()).getDescriptor(); if (descriptor instanceof ShellStep.DescriptorImpl || descriptor instanceof BatchScriptStep.DescriptorImpl) { shell++; } } } assertEquals(42*3,shell); } }); }
@Issue("JENKINS-42027") @Test public void globalConfigPersists() throws Exception { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { GlobalConfig.get().setDockerLabel("config_docker"); GlobalConfig.get().save(); } }); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { assertEquals("config_docker", GlobalConfig.get().getDockerLabel()); } }); }
@Test public void scmPickle() throws Exception { story.addStep(new Statement() { @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); } }); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { SemaphoreStep.success("wait/1", null); WorkflowJob p = story.j.jenkins.getItemByFullName("p/master", WorkflowJob.class); assertNotNull(p); WorkflowRun b1 = p.getLastBuild(); assertNotNull(b1); assertEquals(1, b1.getNumber()); story.j.assertLogContains("initial content", story.j.waitForCompletion(b1)); SCMBinderTest.assertRevisionAction(b1); } }); }
/** * The first baby step. */ @Test public void minimumViableParallelRun() throws Exception { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { p = jenkins().createProject(WorkflowJob.class, "demo"); p.setDefinition(new CpsFlowDefinition(join( "node {", " x = parallel( a: { echo('echo a'); return 1; }, b: { echo('echo b'); return 2; } )", " assert x.a==1", " assert x.b==2", "}" ), false)); startBuilding().get(); // 15, SECONDS); assertBuildCompletedSuccessfully(); buildTable(); shouldHaveParallelStepsInTheOrder("a", "b"); } }); }
/** * Restart Jenkins while workflow is executing to make sure it suspends all right */ @Test public void demo() throws Exception { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { p = jenkins().createProject(WorkflowJob.class, "demo"); p.setDefinition(new CpsFlowDefinition("semaphore 'wait'", false)); startBuilding(); SemaphoreStep.waitForStart("wait/1", b); assertTrue(b.isBuilding()); liveness(); } }); story.addStep(new Statement() { @Override public void evaluate() throws Throwable { rebuildContext(story.j); assertThatWorkflowIsSuspended(); for (int i = 0; i < 600 && !Queue.getInstance().isEmpty(); i++) { Thread.sleep(100); } liveness(); SemaphoreStep.success("wait/1", null); story.j.assertBuildStatusSuccess(story.j.waitForCompletion(b)); } }); } private void liveness() {
@Test public void cli() throws Exception { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p"); // As in loadStep, will set up a main and auxiliary script. FilePath f = story.j.jenkins.getWorkspaceFor(p).child("f.groovy"); f.write("'original text'", null); p.setDefinition(new CpsFlowDefinition("node {def t = load 'f.groovy'; echo \"got ${t}\"}", true)); WorkflowRun b1 = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0)); story.j.assertLogContains("got original text", b1); // s/got/received/ on main script assertEquals(0, new CLICommandInvoker(story.j, "replay-pipeline").withStdin(IOUtils.toInputStream("node {def t = load 'f.groovy'; echo \"received ${t}\"}")).invokeWithArgs("p").returnCode()); story.j.waitUntilNoActivity(); WorkflowRun b2 = p.getLastBuild(); assertEquals(2, b2.getNumber()); story.j.assertLogContains("received original text", b2); // s/original/new/ on auxiliary script, and explicitly asking to replay #1 rather than the latest assertEquals(0, new CLICommandInvoker(story.j, "replay-pipeline").withStdin(IOUtils.toInputStream("'new text'")).invokeWithArgs("p", "-n", "1", "-s", "Script1").returnCode()); story.j.waitUntilNoActivity(); WorkflowRun b3 = p.getLastBuild(); assertEquals(3, b3.getNumber()); // Main script picked up from #1, not #2. story.j.assertLogContains("got new text", b3); } }); }
@Test public void localMethodCallWithinBranch2() { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { p = jenkins().createProject(WorkflowJob.class, "demo"); p.setDefinition(new CpsFlowDefinition(join( "def notify(msg) {", " echo msg", "}", "node {", " ws {", " echo 'start'", " parallel(one: {", " notify('one')", " }, two: {", " notify('two')", " })", " echo 'end'", " }", "}" ), false)); startBuilding().get(); assertBuildCompletedSuccessfully(); story.j.assertLogContains("one", b); story.j.assertLogContains("two", b); } }); }
@Issue("JENKINS-34645") @Test public void stringSplit() { rr.addStep(new Statement() { @Override public void evaluate() throws Throwable { WorkflowJob p = rr.j.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("for (x in 'a;b'.split(';')) {sleep 1; echo(/running in $x/)}", true)); rr.j.assertLogContains("running in b", rr.j.buildAndAssertSuccess(p)); } }); }